Skip to content

Commit f7e3f7a

Browse files
authored
Merge pull request #272099 from RoseHJM/ade-extensible-terraform-image
ADE - Terraform Custom Runner how-to article
2 parents bb64263 + a1a83ad commit f7e3f7a

File tree

4 files changed

+225
-1
lines changed

4 files changed

+225
-1
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
---
2+
title: ADE extensibility model for custom Terraform images
3+
titleSuffix: Azure Deployment Environments
4+
description: Learn how to use the ADE extensibility model to build and utilize custom Terraform images within your environment definitions for deployment environments.
5+
ms.service: deployment-environments
6+
author: RoseHJM
7+
ms.author: rosemalcolm
8+
ms.date: 04/15/2024
9+
ms.topic: how-to
10+
11+
#customer intent: As a developer, I want to learn how to build and utilize custom images within my environment definitions for deployment environments.
12+
---
13+
14+
# Configure a container image to execute deployments with Terraform
15+
16+
In this article, you learn how to build and utilize a custom image within your environment definitions for deployments in Azure Deployment Environments (ADE). You learn how to configure a custom image to provision infrastructure using the Terraform Infrastructure-as-Code (IaC) framework.
17+
18+
ADE supports an extensibility model that enables you to create custom images that you can use in your environment definitions. To leverage this extensibility model, you can create your own custom images, and store them in a public container registry. You can then reference these images in your environment definitions to deploy your environments.
19+
20+
The ADE team provides a selection of images to get you started, which you can see in the [Runner-Images](https://github.com/Azure/deployment-environments/tree/custom-runner-private-preview/Runner-Images) folder.
21+
22+
The ADE CLI is a tool that allows you to build custom images by using ADE base images. You can use the ADE CLI to customize your deployments and deletions to fit your workflow. The ADE CLI is preinstalled on the sample images. To learn more about the ADE CLI, see the [CLI Custom Runner Image reference](https://aka.ms/deployment-environments/ade-cli-reference).
23+
24+
## Prerequisites
25+
26+
- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
27+
28+
## Create and build a Docker image by using Terraform
29+
30+
In this example, you learn how to build a Docker image to utilize ADE deployments and access the ADE CLI, basing your image on one of the ADE authored images.
31+
32+
### FROM statement
33+
34+
Include a FROM statement within a created DockerFile for your new image pointing to a sample image hosted on Microsoft Artifact Registry.
35+
36+
Here's an example FROM statement, referencing the sample core image:
37+
38+
```docker
39+
FROM mcr.microsoft.com/deployment-environments/runners/core:latest
40+
```
41+
42+
This statement pulls the most recently published core image, and makes it a basis for your custom image.
43+
44+
### Install Terraform in a Dockerfile
45+
46+
You can install the Terraform CLI to an executable location so that it can be used in your deployment and deletion scripts. Here's an example of that process, installing version 1.5.5 of the Terraform CLI:
47+
48+
```azure cli
49+
RUN wget -O terraform.zip https://releases.hashicorp.com/terraform/1.7.4/terraform_1.5.5_linux_amd64.zip
50+
RUN unzip terraform.zip && rm terraform.zip
51+
RUN mv terraform /usr/bin/terraform
52+
```
53+
54+
The ADE sample images are based on the Azure CLI image, and have the ADE CLI and JQ packages preinstalled. You can learn more about the [Azure CLI](/cli/azure/), and the [JQ package](https://devdocs.io/jq/).
55+
56+
To install any more packages you need within your image, use the RUN statement.
57+
58+
### Execute operation shell scripts
59+
60+
Within the sample images, operations are determined and executed based on the operation name. Currently, the two operation names supported are *deploy* and *delete*.
61+
62+
To set up your custom image to utilize this structure, specify a folder at the level of your Dockerfile named *scripts*, and specify two files, *deploy.sh*, and *delete.sh*. The deploy shell script runs when your environment is created or redeployed, and the delete shell script runs when your environment is deleted. You can see examples of shell scripts in the repository under the [Runner-Images folder for the ARM-Bicep](https://github.com/Azure/deployment-environments/tree/custom-runner-private-preview/Runner-Images/ARM-Bicep) image.
63+
64+
To ensure these shell scripts are executable, add the following lines to your Dockerfile:
65+
66+
```docker
67+
COPY scripts/* /scripts/
68+
RUN find /scripts/ -type f -iname "*.sh" -exec dos2unix '{}' '+'
69+
RUN find /scripts/ -type f -iname "*.sh" -exec chmod +x {} \;
70+
```
71+
72+
### Author operation shell scripts to use the Terraform CLI
73+
There are three steps to deploy infrastructure via Terraform:
74+
1. `terraform init` - initializes the Terraform CLI to perform actions within the working directory
75+
1. `terraform plan` - develops a plan based on the incoming Terraform infrastructure files and variables, and any existing state files, and develops steps needed to create or update infrastructure specified in the *.tf* files
76+
1. `terraform apply` - applies the plan to create new or update existing infrastructure in Azure
77+
78+
During the core image's entrypoint, any existing state files are pulled into the container and the directory saved under the environment variable ```$ADE_STORAGE```. Additionally, any parameters set for the current environment stored under the variable ```$ADE_OPERATION_PARAMETERS```. In order to access the existing state file, and set your variables within a *.tfvars.json* file, run the following commands:
79+
```bash
80+
EnvironmentState="$ADE_STORAGE/environment.tfstate"
81+
EnvironmentPlan="/environment.tfplan"
82+
EnvironmentVars="/environment.tfvars.json"
83+
84+
echo "$ADE_OPERATION_PARAMETERS" > $EnvironmentVars
85+
```
86+
87+
Additionally, to utilize ADE's privileges to deploy infrastructure inside your subscription, your script needs to use ADE's Managed Service Identity (MSI) when provisioning infrastructure by using the Terraform AzureRM provider. If your deployment needs special permissions to complete your deployment, such as particular roles, assign those permissions to the project environment type's identity that is being used for your environment deployment. ADE sets the relevant environment variables, such as the client, tenant, and subscription IDs within the core image's entrypoint, so run the following commands to ensure the provider uses ADE's MSI:
88+
```bash
89+
export ARM_USE_MSI=true
90+
export ARM_CLIENT_ID=$ADE_CLIENT_ID
91+
export ARM_TENANT_ID=$ADE_TENANT_ID
92+
export ARM_SUBSCRIPTION_ID=$ADE_SUBSCRIPTION_ID
93+
```
94+
95+
If you have other variables to reference within your template that aren't specified in your environment's parameters, set environment variables using the prefix *TF_VAR*. A list of provided ADE environment variables is provided [here](insert link). An example of those commands could be;
96+
```bash
97+
export TF_VAR_resource_group_name=$ADE_RESOURCE_GROUP_NAME
98+
export TF_VAR_ade_env_name=$ADE_ENVIRONMENT_NAME
99+
export TF_VAR_env_name=$ADE_ENVIRONMENT_NAME
100+
export TF_VAR_ade_subscription=$ADE_SUBSCRIPTION_ID
101+
export TF_VAR_ade_location=$ADE_ENVIRONMENT_LOCATION
102+
export TF_VAR_ade_environment_type=$ADE_ENVIRONMENT_TYPE
103+
```
104+
105+
Now, you can run the steps listed previously to initialize the Terraform CLI, generate a plan for provisioning infrastructure, and apply a plan during your deployment script:
106+
```bash
107+
terraform init
108+
terraform plan -no-color -compact-warnings -refresh=true -lock=true -state=$EnvironmentState -out=$EnvironmentPlan -var-file="$EnvironmentVars"
109+
terraform apply -no-color -compact-warnings -auto-approve -lock=true -state=$EnvironmentState $EnvironmentPlan
110+
```
111+
112+
During your deletion script, you can add the `destroy` flag to your plan generation to delete the existing resources, as shown in the following example:
113+
```bash
114+
terraform init
115+
terraform plan -no-color -compact-warnings -destroy -refresh=true -lock=true -state=$EnvironmentState -out=$EnvironmentPlan -var-file="$EnvironmentVars"
116+
terraform apply -no-color -compact-warnings -auto-approve -lock=true -state=$EnvironmentState $EnvironmentPlan
117+
```
118+
119+
Finally, to make the outputs of your deployment uploaded and accessible when accessing your environment via the Azure CLI, transform the output object from Terraform to the ADE-specified format through the JQ package. Set the value to the $ADE_OUTPUTS environment variable, as shown in the following example:
120+
```bash
121+
tfOutputs=$(terraform output -state=$EnvironmentState -json)
122+
# Convert Terraform output format to ADE format.
123+
tfOutputs=$(jq 'walk(if type == "object" then
124+
if .type == "bool" then .type = "boolean"
125+
elif .type == "list" then .type = "array"
126+
elif .type == "map" then .type = "object"
127+
elif .type == "set" then .type = "array"
128+
elif (.type | type) == "array" then
129+
if .type[0] == "tuple" then .type = "array"
130+
elif .type[0] == "object" then .type = "object"
131+
elif .type[0] == "set" then .type = "array"
132+
else .
133+
end
134+
else .
135+
end
136+
else .
137+
end)' <<< "$tfOutputs")
138+
139+
echo "{\"outputs\": $tfOutputs}" > $ADE_OUTPUTS
140+
```
141+
142+
### Build the image
143+
144+
Before you build the image to be pushed to your registry, ensure the [Docker Engine is installed](https://docs.docker.com/desktop/) on your computer. Then, navigate to the directory of your Dockerfile, and run the following command:
145+
146+
```docker
147+
docker build . -t {YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}
148+
```
149+
150+
For example, if you want to save your image under a repository within your registry named `customImage`, and upload with the tag version of `1.0.0`, you would run:
151+
152+
```docker
153+
docker build . -t {YOUR_REGISTRY}.azurecr.io/customImage:1.0.0
154+
```
155+
156+
## Push the Docker image to a registry
157+
158+
In order to use custom images, you need to set up a publicly accessible image registry with anonymous image pull enabled. This way, Azure Deployment Environments can access your custom image to execute in our container.
159+
160+
Azure Container Registry is an Azure offering that stores container images and similar artifacts.
161+
162+
To create a registry, which can be done through the Azure CLI, the Azure portal, PowerShell commands, and more, follow one of the [quickstarts](/azure/container-registry/container-registry-get-started-azure-cli).
163+
164+
To set up your registry to have anonymous image pull enabled, run the following commands in the Azure CLI:
165+
166+
```azurecli
167+
az login
168+
az acr login -n {YOUR_REGISTRY}
169+
az acr update -n {YOUR_REGISTRY} --public-network-enabled true
170+
az acr update -n {YOUR_REGISTRY} --anonymous-pull-enabled true
171+
```
172+
173+
When you're ready to push your image to your registry, run the following command:
174+
175+
```docker
176+
docker push {YOUR_REGISTRY}.azurecr.io/{YOUR_IMAGE_LOCATION}:{YOUR_TAG}
177+
```
178+
179+
## Connect the image to your environment definition
180+
181+
When authoring environment definitions to use your custom image in their deployment, edit the `runner` property on the manifest file (environment.yaml or manifest.yaml).
182+
183+
```yaml
184+
runner: "{YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}"
185+
```
186+
187+
## Access operation logs and error details
188+
189+
ADE stores error details for a failed deployment the *$ADE_ERROR_LOG* file.
190+
191+
To troubleshoot a failed deployment:
192+
193+
1. Sign in to the [Developer Portal](https://devportal.microsoft.com/).
194+
1. Identify the environment that failed to deploy, and select **See details**.
195+
196+
:::image type="content" source="media/how-to-configure-extensibility-terraform-container-image/failed-deployment-card.png" alt-text="Screenshot showing failed deployment error details, specifically an invalid name for a storage account." lightbox="media/how-to-configure-extensibility-terraform-container-image/failed-deployment-card.png":::
197+
198+
1. Review the error details in the **Error Details** section.
199+
200+
:::image type="content" source="media/how-to-configure-extensibility-terraform-container-image/deployment-error-details.png" alt-text="Screenshot showing a failed deployment of an environment with the See Details button displayed." lightbox="media/how-to-configure-extensibility-terraform-container-image/deployment-error-details.png":::
201+
202+
Additionally, you can use the Azure CLI to view an environment's error details using the following command:
203+
```bash
204+
az devcenter dev environment show --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}
205+
```
206+
207+
To view the operation logs for an environment deployment or deletion, use the Azure CLI to retrieve the latest operation for your environment, and then view the logs for that operation ID.
208+
209+
```bash
210+
# Get list of operations on the environment, choose the latest operation
211+
az devcenter dev environment list-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}
212+
# Using the latest operation ID, view the operation logs
213+
az devcenter dev environment show-logs-by-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME} --operation-id {LATEST_OPERATION_ID}
214+
```
215+
216+
217+
## Related content
218+
219+
- [ADE CLI Custom Runner Image reference](https://aka.ms/deployment-environments/ade-cli-reference)
Loading
Loading

articles/deployment-environments/toc.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ items:
6363
displayName: custom image, custom runner, extensibility
6464
- name: Configure ARM/Bicep container image to execute deployments
6565
href: how-to-configure-extensibility-bicep-container-image.md
66-
displayName: custom image, custom runner, extensibility
66+
displayName: custom image, custom runner, extensibility
67+
- name: Configure Terraform container image to execute deployments
68+
href: how-to-configure-extensibility-terraform-container-image.md
69+
displayName: custom image, custom runner, extensibility
6770
- name: Create and manage environments
6871
expanded: false
6972
items:
@@ -73,6 +76,8 @@ items:
7376
href: how-to-manage-environments.md
7477
- name: Create environments with Azure CLI
7578
href: how-to-create-access-environments.md
79+
- name: Custom image support with Terraform
80+
href: how-to-configure-extensibility-terraform-container-image.md
7681
- name: Manage costs
7782
expanded: false
7883
items:

0 commit comments

Comments
 (0)