Compartir a través de


Configuración de una imagen de contenedor para ejecutar implementaciones con Terraform

En este artículo aprenderá a compilar imágenes de contenedor de Terraform personalizadas para implementar sus definiciones de entorno en Azure Deployment Environments (ADE). Aprenderá a configurar una imagen personalizada para aprovisionar la infraestructura mediante el marco de infraestructura como código (IaC) de Terraform.

Una definición de entorno comprende al menos dos archivos: un archivo de plantilla, como main.tf, y un archivo de manifiesto llamado environment.yaml. Se usa un contenedor para implementar la definición de entorno que usa Terraform.

El modelo de extensibilidad de ADE le permite crear imágenes de contenedor personalizadas para usarlas con las definiciones de entorno. Mediante el modelo de extensibilidad, puede crear sus propias imágenes de contenedor personalizadas y almacenarlas en un registro de contenedor como DockerHub. Después, puede hacer referencia a estas imágenes en las definiciones de entorno para implementar los entornos.

La CLI de ADE es una herramienta que le permite usar imágenes base de ADE para compilar imágenes personalizadas. Con la CLI de ADE, puede personalizar las implementaciones y las eliminaciones para ajustarse al flujo de trabajo. La CLI de ADE está preinstalada en las imágenes de muestra. Para obtener más información sobre la CLI de ADE, consulte la referencia de imagen de ejecutor personalizado de la CLI.

Requisitos previos

Creación y compilación de una imagen de Docker mediante Terraform

En este ejemplo, aprenderá a compilar una imagen de Docker para usar las implementaciones de ADE y acceder a la CLI de ADE; como base de la imagen, se tomará una de las imágenes creadas por ADE.

Para crear una imagen configurada para ADE, siga estos pasos:

  1. Base la imagen en una imagen de muestra creada por ADE o en una imagen de su elección mediante la instrucción FROM.
  2. Instale los paquetes necesarios para la imagen mediante la instrucción RUN.
  3. Cree una carpeta de scripts en el mismo nivel que Dockerfile, almacene en ella sus archivos deploy.sh y delete.sh y asegúrese de que esos scripts se puedan detectar y ejecutar dentro del contenedor que ha creado. Este paso es necesario para que la implementación funcione con la imagen principal de ADE.
  4. Compile e inserte la imagen en el registro de contenedor y asegúrese de que ADE pueda acceder a ella.
  5. Haga referencia a la imagen en la propiedad runner de la definición del entorno.

Seleccione una imagen de contenedor de ejemplo mediante la instrucción FROM

Incluya una instrucción FROM en un DockerFile creado para la nueva imagen que apunte a una imagen de ejemplo hospedada en el Registro de artefactos Microsoft.

A continuación, se muestra una instrucción FROM de ejemplo que hace referencia a la imagen principal de muestra:

FROM mcr.microsoft.com/deployment-environments/runners/core:latest

Esta instrucción extrae la última imagen principal publicada y la convierte en base de la imagen personalizada.

Instalación de Terraform en un Dockerfile

Puede instalar la CLI de Terraform en una ubicación ejecutable para que se pueda usar en los scripts de implementación y eliminación.

Este es un ejemplo de ese proceso, instalando la versión 1.7.5 de la CLI de Terraform:

RUN wget -O terraform.zip https://releases.hashicorp.com/terraform/1.7.5/terraform_1.7.5_linux_amd64.zip
RUN unzip terraform.zip && rm terraform.zip
RUN mv terraform /usr/bin/terraform

Sugerencia

Puede obtener la dirección URL de descarga de su versión preferida de la CLI de Terraform desde las versiones de Hashicorp.

Las imágenes de muestra de ADE se basan en la imagen de la CLI de Azure y tienen preinstalados los paquetes JQ y la CLI de ADE. Aquí puede obtener más información sobre la CLI de Azurey el paquete JQ.

Para instalar otros paquetes que necesite en la imagen, use la instrucción RUN.

Ejecución de scripts del shell de operaciones

En las imágenes de muestra, las operaciones se determinan y ejecutan en función de su nombre. Actualmente, los dos nombres de operación admitidos son deploy y delete.

Para configurar la imagen personalizada de forma que use esta estructura, especifique una carpeta en el nivel de Dockerfile denominada scripts y especifique dos archivos, deploy.sh y delete.sh. El script del shell deploy se ejecuta al crear o volver a implementar el entorno y el script del shell delete se ejecuta al eliminar el entorno. Puede consultar ejemplos de scripts de shell en el repositorio bajo la carpeta Runner-Images para la imagen ARM-Bicep.

Para asegurarse de que estos scripts de shell sean ejecutables, agregue las siguientes líneas al Dockerfile:

COPY scripts/* /scripts/
RUN find /scripts/ -type f -iname "*.sh" -exec dos2unix '{}' '+'
RUN find /scripts/ -type f -iname "*.sh" -exec chmod +x {} \;

Creación de scripts de shell de operación para usar la CLI de Terraform

Hay tres pasos para implementar la infraestructura mediante Terraform:

  1. terraform init: inicializa la CLI de Terraform para realizar acciones en el directorio de trabajo
  2. terraform plan: desarrolla un plan basado en los archivos y variables de infraestructura de Terraform entrantes, así como en los archivos de estado existentes, y desarrolla los pasos necesarios para crear o actualizar la infraestructura especificada en los archivos .tf
  3. terraform apply: aplica el plan para crear una infraestructura existente o actualizarla en Azure

Durante el punto de entrada de la imagen principal, cualquier archivo de estado existente se introduce en el contenedor y el directorio se guarda bajo la variable de entorno $ADE_STORAGE. Además, los parámetros establecidos para el entorno actual almacenados en la variable $ADE_OPERATION_PARAMETERS. Para acceder al archivo de estado existente y establecer sus variables dentro de un archivo .tfvars.json, ejecute los siguientes comandos:

EnvironmentState="$ADE_STORAGE/environment.tfstate"
EnvironmentPlan="/environment.tfplan"
EnvironmentVars="/environment.tfvars.json"

echo "$ADE_OPERATION_PARAMETERS" > $EnvironmentVars

Además, para usar los privilegios de ADE para implementar la infraestructura dentro de su suscripción, su script necesita usar la Identidad de servicio administrada (MSI) al aprovisionar la infraestructura usando el proveedor de Terraform AzureRM. Si su implementación necesita permisos especiales para su finalización, como roles particulares, asigne esos permisos a la identidad del tipo de entorno del proyecto que se está usando para su implementación del entorno. ADE establece las variables de entorno pertinentes, como los id. de cliente, inquilino y suscripción dentro del punto de entrada de la imagen principal, así que ejecute los siguientes comandos para asegurarse de que el proveedor usa el MSI de ADE:

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

Si tiene otras variables a las que hacer referencia dentro de su plantilla que no estén especificadas en los parámetros de su entorno, establezca variables de entorno usando el prefijo TF_VAR. Se proporciona una lista de las variables de entorno de ADE proporcionadas referencia de variables de la CLI del entorno de implementación de Azure. Un ejemplo de esos comandos podría ser;

export TF_VAR_resource_group_name=$ADE_RESOURCE_GROUP_NAME
export TF_VAR_ade_env_name=$ADE_ENVIRONMENT_NAME
export TF_VAR_env_name=$ADE_ENVIRONMENT_NAME
export TF_VAR_ade_subscription=$ADE_SUBSCRIPTION_ID
export TF_VAR_ade_location=$ADE_ENVIRONMENT_LOCATION
export TF_VAR_ade_environment_type=$ADE_ENVIRONMENT_TYPE

Ahora, puede ejecutar los pasos enumerados anteriormente para inicializar la CLI de Terraform, generar un plan para la infraestructura de aprovisionamiento y aplicar un plan durante el script de implementación:

terraform init
terraform plan -no-color -compact-warnings -refresh=true -lock=true -state=$EnvironmentState -out=$EnvironmentPlan -var-file="$EnvironmentVars"
terraform apply -no-color -compact-warnings -auto-approve -lock=true -state=$EnvironmentState $EnvironmentPlan

Durante el script de eliminación, puede agregar la marca destroy a la generación del plan para eliminar los recursos existentes, como se muestra en el ejemplo siguiente:

terraform init
terraform plan -no-color -compact-warnings -destroy -refresh=true -lock=true -state=$EnvironmentState -out=$EnvironmentPlan -var-file="$EnvironmentVars"
terraform apply -no-color -compact-warnings -auto-approve -lock=true -state=$EnvironmentState $EnvironmentPlan

Por último, para que las salidas de la implementación se carguen y sean accesibles al acceder al entorno a través de la CLI de Azure, transforme el objeto de salida de Terraform al formato especificado por ADE mediante el paquete JQ. Establezca el valor en la variable de entorno $ADE_OUTPUTS, como se muestra en el ejemplo siguiente:

tfOutputs=$(terraform output -state=$EnvironmentState -json)
# Convert Terraform output format to ADE format.
tfOutputs=$(jq 'walk(if type == "object" then 
            if .type == "bool" then .type = "boolean" 
            elif .type == "list" then .type = "array" 
            elif .type == "map" then .type = "object" 
            elif .type == "set" then .type = "array" 
            elif (.type | type) == "array" then 
                if .type[0] == "tuple" then .type = "array" 
                elif .type[0] == "object" then .type = "object" 
                elif .type[0] == "set" then .type = "array" 
                else . 
                end 
            else . 
            end 
        else . 
        end)' <<< "$tfOutputs")

echo "{\"outputs\": $tfOutputs}" > $ADE_OUTPUTS

Compilación de la imagen

Antes de compilar la imagen para insertarla en el registro, asegúrese de que Docker Engine esté instalado en el equipo. A continuación, vaya al directorio del Dockerfile y ejecute el siguiente comando:

docker build . -t {YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}

Por ejemplo, si quiere guardar la imagen en un repositorio dentro del registro denominado customImage y cargar la versión de etiqueta de 1.0.0, debería ejecutar:

docker build . -t {YOUR_REGISTRY}.azurecr.io/customImage:1.0.0

Inserción de la imagen de Docker en un registro

Para usar imágenes personalizadas, debe configurar un registro de imágenes accesible de forma pública que tenga habilitada la extracción anónima de imágenes. De este modo, Azure Deployment Environments puede acceder a la imagen personalizada para ejecutarla en nuestro contenedor.

Azure Container Registry es una oferta de Azure que almacena imágenes de contenedor y artefactos similares.

Para crear un registro, lo cual puede realizarse mediante la CLI de Azure, Azure Portal o comandos de PowerShell entre otros métodos, siga uno de los inicios rápidos correspondientes.

Para configurar el registro de forma que tenga habilitada la extracción anónima de imágenes, ejecute los siguientes comandos en la CLI de Azure:

az login
az acr login -n {YOUR_REGISTRY}
az acr update -n {YOUR_REGISTRY} --public-network-enabled true
az acr update -n {YOUR_REGISTRY} --anonymous-pull-enabled true

Cuando esté listo para insertar la imagen en el registro, ejecute el siguiente comando:

docker push {YOUR_REGISTRY}.azurecr.io/{YOUR_IMAGE_LOCATION}:{YOUR_TAG}

Conexión de la imagen a la definición del entorno

Al crear definiciones de entorno para usar la imagen personalizada en su implementación, edite la propiedad runner en el archivo de manifiesto (environment.yaml o manifest.yaml).

runner: "{YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}"

Compilación de una imagen de contenedor con un script

Microsoft proporciona un script de inicio rápido para ayudarle a empezar. El script compila la imagen y la inserta en una instancia específica de Azure Container Registry (ACR) en el repositorio ade con la etiqueta latest.

Para usar el script, debe:

  1. Configurar un Dockerfile y una carpeta de scripts que admitan el modelo de extensibilidad de ADE.
  2. Proporcionar un nombre de registro y su directorio para la imagen personalizada.
  3. Tener instalada la CLI de Azure y Docker Desktop en las variables PATH.
  4. Tener permisos para insertar en el registro especificado.

Puede ejecutar el script aquí.

Para llamar al script, use el siguiente comando en PowerShell:

.\quickstart-image-build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}'

Además, si quiere insertar en un repositorio y un nombre de etiqueta específicos, puede ejecutar:

.\quickstart-image.build.ps1 -Registry '{YOUR_REGISTRY}' -Directory '{DIRECTORY_TO_YOUR_IMAGE}' -Repository '{YOUR_REPOSITORY}' -Tag '{YOUR_TAG}'

Acceso a registros de operaciones y detalles de errores

ADE almacena los detalles de los errores de una implementación incorrecta en el archivo $ADE_ERROR_LOG dentro del contenedor.

Para solucionar los problemas de una implementación con errores:

  1. Inicie sesión en el Portal para desarrolladores.

  2. Identifique el entorno que no se ha podido implementar y seleccione Ver detalles.

    Captura de pantalla que muestra los detalles de error de la implementación incorrecta; en concreto, un nombre no válido para una cuenta de almacenamiento.

  3. Revise los detalles correspondientes en la sección Detalles del error.

    Captura de pantalla que muestra una implementación incorrecta donde aparece el botón Ver detalles.

También puede usar la CLI de Azure para ver los detalles de los errores de un entorno con el siguiente comando:

az devcenter dev environment show --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}

Para ver los registros de operaciones de la implementación o eliminación de un entorno, use la CLI de Azure a fin de recuperar la operación más reciente para el entorno y, a continuación, consulte los registros de ese identificador de operación.

# Get list of operations on the environment, choose the latest operation
az devcenter dev environment list-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}
# Using the latest operation ID, view the operation logs
az devcenter dev environment show-logs-by-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME} --operation-id {LATEST_OPERATION_ID}