Configure container image to execute deployments
Azure Deployment Environments (ADE) supports an extensibility model that enables you to Configure your environment definition with your preferred IaC template framework. You can store custom images in a container registry like Azure Container Registry (ACR) or Docker Hub and then reference them in your environment definitions to deploy environments.
In this article, you learn how to build custom Bicep container images to deploy your environment definitions in ADE. You learn how to use a standard image provided by Microsoft or how to configure a custom image provision infrastructure using the Bicep Infrastructure-as-Code (IaC) framework.
In this article, you learn how to build custom Terraform container images to create deployment environments with Azure Deployment Environments (ADE). You learn how to configure a custom image to provision infrastructure using the Terraform Infrastructure-as-Code (IaC) framework.
In this article, you learn how to utilize Pulumi for deployments in ADE. You learn how to use a standard image provided by Pulumi or how to configure a custom image to provision infrastructure using the Pulumi Infrastructure-as-Code (IaC) framework.
Prerequisites
- An Azure account with an active subscription. Create an account for free.
- Azure Deployment Environments set up in your Azure subscription.
- To set up ADE, follow the Quickstart: Configure Azure Deployment Environments.
Use container images with ADE
You can take one of the following approaches to use container images with ADE:
- Use a standard container image For simple scenarios, use the standard ARM-Bicep container image provided by ADE.
- Create a custom container image For more complex scenarios, create a custom container image that meets your specific requirements.
Use a standard container image
ADE supports Azure Resource Manager (ARM) and Bicep without requiring any extra configuration. You can create an environment definition that deploys Azure resources for a deployment environment by adding the template files (like azuredeploy.json and environment.yaml) to your catalog. ADE then uses the standard ARM-Bicep container image to create the deployment environment.
In the environment.yaml file, the runner
property specifies the location of the container image you want to use. To use the standard image published on the Microsoft Artifact Registry, use the respective identifiers runner
.
The following example shows a runner
that references the standard ARM-Bicep container image:
name: WebApp
version: 1.0.0
summary: Azure Web App Environment
description: Deploys a web app in Azure without a datastore
runner: Bicep
templatePath: azuredeploy.json
You can see the standard Bicep container image in the ADE standard repository under the Runner-Images folder for the ARM-Bicep image.
For more information about how to create environment definitions that use the ADE container images to deploy your Azure resources, see Add and configure an environment definition.
Create a custom container image
Create a custom container image by using a script
Creating a custom container image allows you to customize your deployments to fit your requirements. You can create and build an image based on the ADE standard image and push it to your container registry by using a quick start script provided by Microsoft. You can find the script in the Deployment Environments repo. To use the quick start script, fork the repo and then run the script locally.
The script builds an image and pushes it to the specified Azure Container Registry (ACR) under the repository 'ade' and the tag 'latest'. This script requires your registry name and directory for your custom image, have the Azure CLI and Docker Desktop installed and in your PATH variables, and requires that you have permissions to push to the specified registry.
To use the script, you must:
- Create a Dockerfile and scripts folder to support the ADE extensibility model.
- Supply a registry name and directory for your custom image.
- Have the Azure CLI and Docker Desktop installed and in your PATH variables.
- Have Docker Desktop running.
- Have permissions to push to the specified registry.
You can call the script using the following command in PowerShell:
.\quickstart-image-build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}'
Additionally, if you would like to push to a specific repository and tag name, you can run:
.\quickstart-image.build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}' -Repository '{YOUR_REPOSITORY}' -Tag '{YOUR_TAG}'
To use the image in your environment deployments, you need to add the location of the image to your manifest file Connect the image to your environment definition and you might need to configure permissions for the ACR to make the custom image available to ADE.
Use container images with ADE
You can take one of the following approaches to use container images with ADE:
- Create a custom container image by using a script: Use the published script to create a Terraform specific image.
- Create a custom container image leveraging a GitHub workflow: Use the published GitHub workflow from the Leveraging ADE's Extensibility Model With Terraform repository.
- Create a custom container image manually: Create a customized Terraform specific image manually
Create a custom container image
Create a custom container image by using a script
Creating a custom container image allows you to customize your deployments to fit your requirements. You can build an image based on the ADE standard image and push it to your container registry by using a quick start script provided by Microsoft. You can find the script in the Deployment Environments with Terraform repo. To use the quick start script, fork the repo and then run the script locally.
To use the quickstart script to quickly build and push this sample image to an Azure Container Registry, you will need to:
- Fork this repository into your personal account.
- Ensure the Azure CLI and the Docker Desktop application are installed on your computer and within your PATH variables.
- Ensure you have permissions to push images to your selected Azure Container Registry.
The script builds an image and pushes it to the specified Azure Container Registry (ACR) under the repository 'ade' and the tag 'latest'. This script requires your registry name and directory for your custom image, have the Azure CLI and Docker Desktop installed and in your PATH variables, and requires that you have permissions to push to the specified registry. You can call the script using the following command in PowerShell:
.\quickstart-image-build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}'
Additionally, if you would like to push to a specific repository and tag name, you can run:
.\quickstart-image.build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}' -Repository '{YOUR_REPOSITORY}' -Tag '{YOUR_TAG}'
To use the image in your environment deployments, you need to add the location of the image to your manifest file Connect the image to your environment definition and you might need to configure permissions for the ACR to make the custom image available to ADE.
Use a standard container image provided by Pulumi
The Pulumi team provides a prebuilt image to get you started, which you can see in the Runner-Image folder. This image is publicly available at Pulumi's Docker Hub as pulumi/azure-deployment-environments
, so you can use it directly from your ADE environment definitions.
Here's a sample environment.yaml file that utilizes the prebuilt image:
name: SampleDefinition
version: 1.0.0
summary: First Pulumi-Enabled Environment
description: Deploys a Storage Account with Pulumi
runner: pulumi/azure-deployment-environments:0.1.0
templatePath: Pulumi.yaml
You can find a few sample environment definitions in the Environments folder.
Create a custom image
Creating a custom container image allows you to customize your deployments to fit your requirements. You can create custom images based on the Pulumi standard images, and customize them to meet your requirements. After you complete the image customization, you must build the image and push it to your container registry.
To create an image configured for ADE, follow these steps:
- Create a custom image based on a standard image.
- Install desired packages.
- Configure operation shell scripts.
- Create operation shell scripts that use the Pulumi CLI.
1. Create a custom image based on a standard image
Create a DockerFile that includes a FROM statement pointing to a standard image hosted on Microsoft Artifact Registry.
Here's an example FROM statement, referencing the standard core image:
FROM mcr.microsoft.com/deployment-environments/runners/core:latest
This statement pulls the most recently published core image, and makes it a basis for your custom image.
2. Install required packages
You can install the Pulumi 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 the latest version of the Pulumi CLI:
RUN apk add curl
RUN curl -fsSL https://get.pulumi.com | sh
ENV PATH="${PATH}:/root/.pulumi/bin"
Depending on which programming language you intend to use for Pulumi programs, you might need to install one or more corresponding runtimes. The Python runtime is already available in the base image.
Here's an example of installing Node.js and TypeScript:
# install node.js, npm, and typescript
RUN apk add nodejs npm
RUN npm install typescript -g
The ADE standard 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, and the JQ package.
To install any more packages you need within your image, use the RUN statement.
There are four steps to deploy infrastructure via Pulumi:
pulumi login
- connect to the state storage, either in local file system or in Pulumi Cloudpulumi stack select
- create or select the stack to use for the particular environmentpulumi config set
- pass deployment parameters as Pulumi configuration valuespulumi up
- run the deployment to create new or update existing infrastructure in Azure
During the core image's entrypoint, any existing local state files are pulled into the container and the directory saved under the environment variable $ADE_STORAGE
. In order to access the existing state file, run the following commands:
mkdir -p $ADE_STORAGE
export PULUMI_CONFIG_PASSPHRASE=
pulumi login file://$ADE_STORAGE
To sign in to Pulumi Cloud instead, set your Pulumi access token as an environment variable, and run the following commands:
export PULUMI_ACCESS_TOKEN=YOUR_PULUMI_ACCESS_TOKEN
pulumi login
Any parameters set for the current environment are stored under the variable $ADE_OPERATION_PARAMETERS
. Additionally, the selected Azure region and resource group name are passed in ADE_ENVIRONMENT_LOCATION
and ADE_RESOURCE_GROUP_NAME
respectively. In order to set your Pulumi stack config, run the following commands:
# Create or select the stack for the current environment
pulumi stack select $ADE_ENVIRONMENT_NAME --create
# Store configuration values in durable storage
export PULUMI_CONFIG_FILE=$ADE_STORAGE/Pulumi.$ADE_ENVIRONMENT_NAME.yaml
# Set the Pulumi stack config
pulumi config set azure-native:location $ADE_ENVIRONMENT_LOCATION --config-file $PULUMI_CONFIG_FILE
pulumi config set resource-group-name $ADE_RESOURCE_GROUP_NAME --config-file $PULUMI_CONFIG_FILE
echo "$ADE_OPERATION_PARAMETERS" | jq -r 'to_entries|.[]|[.key, .value] | @tsv' |
while IFS=$'\t' read -r key value; do
pulumi config set $key $value --config-file $PULUMI_CONFIG_FILE
done
Additionally, to utilize ADE privileges to deploy infrastructure inside your subscription, your script needs to use ADE Managed Service Identity (MSI) when provisioning infrastructure by using the Pulumi Azure Native or Azure Classic 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 MSI:
export ARM_USE_MSI=true
export ARM_CLIENT_ID=$ADE_CLIENT_ID
export ARM_TENANT_ID=$ADE_TENANT_ID
export ARM_SUBSCRIPTION_ID=$ADE_SUBSCRIPTION_ID
Now, you can run the pulumi up
command to execute the deployment:
pulumi up --refresh --yes --config-file $PULUMI_CONFIG_FILE
During your deletion script, you can instead run the destroy
command, as shown in the following example:
pulumi destroy --refresh --yes --config-file $PULUMI_CONFIG_FILE
Finally, to make the outputs of your deployment uploaded and accessible when accessing your environment via the Azure CLI, transform the output object from Pulumi to the ADE-specified format through the JQ package. Set the value to the $ADE_OUTPUTS environment variable, as shown in the following example:
stackout=$(pulumi stack output --json | jq -r 'to_entries|.[]|{(.key): {type: "string", value: (.value)}}')
echo "{\"outputs\": ${stackout:-{\}}}" > $ADE_OUTPUTS
Build the custom image
You can build your image using the Docker CLI. Ensure the Docker Engine is installed on your computer. Then, navigate to the directory of your Dockerfile, and run the following command:
docker build . -t {YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}
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:
docker build . -t {YOUR_REGISTRY}.azurecr.io/customImage:1.0.0
Make the custom image available to ADE
In order to use custom images, you need to store them in a container registry. You can use a public container registry or a private container registry. Azure Container Registry (ACR) is highly recommended, due to its tight integration with ADE, the image can be published without allowing public anonymous pull access. You must build your custom container image and push it to a container registry to make it available for use in ADE.
It's also possible to store the image in a different container registry such as Docker Hub, but in that case it needs to be publicly accessible.
Caution
Storing your container image in a registry with anonymous (unauthenticated) pull access makes it publicly accessible. Don't do that if your image contains any sensitive information. Instead, store it in Azure Container Registry (ACR) with anonymous pull access disabled.
To use a custom image stored in ACR, you need to ensure that ADE has appropriate permissions to access your image. When you create an ACR instance, it's secure by default and only allows authenticated users to gain access.
You can use Pulumi to create an Azure Container Registry and publish your image to it. Refer to the Provisioning/custom-image example for a self-contained Pulumi project that creates all the required resources in your Azure account.
Select the appropriate tab to learn more about each approach.
Use a private registry with secured access
By default, access to pull or push content from an Azure Container Registry is only available to authenticated users. You can further secure access to ACR by limiting access from certain networks and assigning specific roles.
To create an instance of ACR, which can be done through the Azure CLI, the Azure portal, PowerShell commands, and more, follow one of the quickstarts.
Limit network access
To secure network access to your ACR, you can limit access to your own networks, or disable public network access entirely. If you limit network access, you must enable the firewall exception Allow trusted Microsoft services to access this container registry.
To disable access from public networks:
Create an ACR instance or use an existing one.
In the Azure portal, go to the ACR that you want to configure.
On the left menu, under Settings, select Networking.
On the Networking page, on the Public access tab, under Public network access, select Disabled.
Under Firewall exception, check that Allow trusted Microsoft services to access this container registry is selected, and then select Save.
Assign the AcrPull role
Creating environments by using container images uses the ADE infrastructure, including projects and environment types. Each project has one or more project environment types, which need read access to the container image that defines the environment to be deployed. To access the images within your ACR securely, assign the AcrPull role to each project environment type.
To assign the AcrPull role to the Project Environment Type:
In the Azure portal, go to the ACR that you want to configure.
On the left menu, select Access Control (IAM).
Select Add > Add role assignment.
Assign the following role. For detailed steps, see Assign Azure roles using the Azure portal.
Setting Value Role Select AcrPull. Assign access to Select User, group, or service principal. Members Enter the name of the project environment type that needs to access the image in the container. The project environment type displays like the following example:
In this configuration, ADE uses the Managed Identity for the PET, whether system assigned or user assigned.
Tip
This role assignment has to be made for every project environment type. It can be automated through the Azure CLI.
When you're ready to push your image to your registry, run the following command:
docker push {YOUR_REGISTRY}.azurecr.io/{YOUR_IMAGE_LOCATION}:{YOUR_TAG}
Connect the image to your environment definition
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).
runner: "{YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}"
To learn more about how to create environment definitions that use the ADE container images to deploy your Azure resources, see Add and configure an environment definition.