Saltar al contenido

CodePipeline: fuente de ECR + configuración de implementación de ECS

Este team de especialistas pasados muchos días de investigación y recopilar de información, dimos con los datos necesarios, queremos que resulte útil para ti para tu plan.

Solución:

Tuve un caso de uso similar y encontré el mismo problema. Una respuesta un poco larga con una solución que aborda mi caso de uso …

  1. Caso de uso: La cuenta de herramientas tiene CodePipeline, que hace que CodeBuild y la ventana acoplable empujen a las cuentas de control de calidad ECR. La imagen tendrá 2 etiquetas: un “hash de confirmación” y “último”. QA Account tiene una canalización que se ejecuta cuando una nueva imagen está disponible y esta canalización implementa la nueva imagen en el clúster de Fargate en QA Account.
  2. Plataforma de implementación: Acciones de implementación estándar de Amazon ECS.
  3. Fuente: ECR.
  4. Causa del problema: Artefacto de salida de la fuente ECR legítimamente solo contiene la información sobre la imagen y no incluye el nombre del contenedor que espera ECS Standard Deploy.
  5. Sugerencia para AWS: Dado el escenario popular de usar ECR como fuente para ECS, podemos argumentar que tenemos la capacidad (opcional) para agregar el nombre del contenedor en el artefacto de salida; esto permitiría la generación de artefactos de salida que son aceptables como entrada para la implementación estándar de ECS.

Según este documento oficial de AWS ECS Standard Deployment espera un – imagedefinitions.json que proporciona el nombre del contenedor y el URI de la imagen. Debería verse así:

[
  
    "name": "sample-app",
    "imageUri": "11111EXAMPLE.dkr.ecr.us-west-2.amazonaws.com/ecs-repo:latest"
  
]

Pero la fuente de ECR produce un artefacto de salida llamado imageDetail.json ejemplo a continuación. Esto no coincide con el formato de entrada esperado para la implementación estándar de ECS, también conocida como imagedefinitions.json, que incluye el nombre del contenedor (nombre) y la implementación falla con un mensaje como Error de implementación:


    "ImageSizeInBytes": "44728918",
    "ImageDigest": "sha256:EXAMPLE11223344556677889900bfea42ea2d3b8a1ee8329ba7e68694950afd3",
    "Version": "1.0",
    "ImagePushedAt": "Mon Jan 21 20:04:00 UTC 2019",
    "RegistryId": "EXAMPLE12233",
    "RepositoryName": "dk-image-repo",
    "ImageURI": "ACCOUNTID.dkr.ecr.us-west-2.amazonaws.com/[email protected]:example3",
    "ImageTags": [
        "latest"
    ]

El enfoque que tomé para solucionar esto es:

  1. En la etapa Fuente: además de la fuente ECR, agregué una fuente de s3 que contiene imagedefinitions.json en un zip.

  2. En la acción de la etapa ECS Deploy me refiero al artefacto de salida de la fuente s3 que contiene imagedefinitions.json en el formato que entiende ECS Standard Deploy.

Nota: El archivo imagedefinitions.json es static en el segmento s3 y siempre se refiere a la última etiqueta de dicha imagen. Entonces, en el grupo de definiciones de imágenes de control de calidad, terminaré con un archivo zip de definiciones de imágenes, es decir, uno por instancia del servicio Fargate.

He exportado mi canalización aquí para referencia general:

{
"pipeline": 
    "roleArn": "arn:aws:iam::ACCOUNTID:role/service-role/AWSCodePipelineServiceRole-REGION-PIPELINENAME",
    "stages": [
        
            "name": "Source",
            "actions": [
                
                    "inputArtifacts": [],
                    "name": "Source",
                    "region": "REGION",
                    "actionTypeId": 
                        "category": "Source",
                        "owner": "AWS",
                        "version": "1",
                        "provider": "ECR"
                    ,
                    "outputArtifacts": [
                        
                            "name": "SourceArtifact"
                        
                    ],
                    "configuration": 
                        "ImageTag": "latest",
                        "RepositoryName": "PIPELINENAME"
                    ,
                    "runOrder": 1
                ,
                
                    "inputArtifacts": [],
                    "name": "sourceimagedeffile",
                    "region": "REGION",
                    "actionTypeId": 
                        "category": "Source",
                        "owner": "AWS",
                        "version": "1",
                        "provider": "S3"
                    ,
                    "outputArtifacts": [
                        
                            "name": "PIPELINENAME-imagedefjson"
                        
                    ],
                    "configuration": 
                        "S3Bucket": "BUCKETNAME",
                        "PollForSourceChanges": "true",
                        "S3ObjectKey": "PIPELINENAME.zip"
                    ,
                    "runOrder": 1
                
            ]
        ,
        
            "name": "Deploy",
            "actions": [
                
                    "inputArtifacts": [
                        
                            "name": "PIPELINENAME-imagedefjson"
                        
                    ],
                    "name": "Deploy",
                    "region": "REGION",
                    "actionTypeId": 
                        "category": "Deploy",
                        "owner": "AWS",
                        "version": "1",
                        "provider": "ECS"
                    ,
                    "outputArtifacts": [],
                    "configuration": 
                        "ClusterName": "FARGATECLUSTERNAME",
                        "ServiceName": "PIPELINENAME",
                        "FileName": "imageDetail.json"
                    ,
                    "runOrder": 1
                
            ]
        
    ],
    "artifactStore": 
        "type": "S3",
        "location": "codepipeline-REGION-555869339681"
    ,
    "name": "PIPELINENAME"

Recientemente tuve que resolver un problema similar en el que quería usar ECR como fuente de mi canalización y hacer que implementara la imagen en ECS. La solución que encontré fue creando 3 etapas:

  • Fuente: ECR
  • Construir: Código personalizado para convertir el artefacto ECR en un artefacto que la etapa de implementación entendería
  • Desplegar: A ECS

Aquí está el archivo buildspec.yml que estoy usando como mi etapa de compilación:

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.7
  build:
    commands:
      - PHP_REPOSITORY_URI=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageURI'].split('@')[0])")
      - IMAGE_TAG=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageTags'][0])")
      - echo $PHP_REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Writing image definitions file...
      - printf '["name":"container","imageUri":"%s"]' $PHP_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
    files: imagedefinitions.json

Básicamente, lo que hace es leer el archivo imageDetail.json y extraer la URL del repositorio de ECR y el TAG y generar un archivo json formateado para la etapa de implementación de ECS, que es solo una etapa estándar sin personalización.

Sección de Reseñas y Valoraciones

Finalizando este artículo puedes encontrar las acotaciones de otros desarrolladores, tú todavía puedes mostrar el tuyo si dominas el tema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *