hoangquyy
hoangquyy

Reputation: 2073

AWS CodeDeploy for ECS EC2 Blue/Green Deploy

I'm trying to deploy my product by using CodePipeline with CodeDeploy for ECS EC2 Blue/Green Deploy but it always return this error when it run:

Container.image contains invalid characters.

I think the error come from 2 files appspec.yaml and taskdef.json because when I using Rolling Deploy, it worked.

This is my config:

appspec.yaml

version: 0.0
Resources:
 - TargetService:
     Type: AWS::ECS::Service
     Properties:
       TaskDefinition: <TASK_DEFINITION>
       LoadBalancerInfo:
         ContainerName: "my-container"
         ContainerPort: 80

taskdef.json

{
  "ipcMode": null,
  "executionRoleArn": null,
  "containerDefinitions": [
    {
      "dnsSearchDomains": null,
      "environmentFiles": null,
      "logConfiguration": null,
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 80,
          "protocol": "tcp",
          "containerPort": 80
        },
        {
          "hostPort": 8000,
          "protocol": "tcp",
          "containerPort": 8000
        }
      ],
      "command": null,
      "linuxParameters": null,
      "cpu": 0,
      "environment": [],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [],
      "workingDirectory": null,
      "secrets": null,
      "dockerSecurityOptions": null,
      "memory": null,
      "memoryReservation": null,
      "volumesFrom": [],
      "stopTimeout": null,
      "image": "<IMAGE1_NAME>",
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": null,
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": null,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null,
      "name": "my-container"
    }
  ],
  "placementConstraints": [],
  "memory": "512",
  "taskRoleArn": null,
  "compatibilities": [
    "EXTERNAL",
    "EC2"
  ],
  "taskDefinitionArn": "<TASK_DEFINITION>",
  "family": "task-definition-name",
  "requiresAttributes": [
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.ecr-auth"
    }
  ],
  "pidMode": null,
  "requiresCompatibilities": [
    "EC2"
  ],
  "networkMode": null,
  "cpu": "512",
  "revision": 17,
  "status": "ACTIVE",
  "inferenceAccelerators": null,
  "proxyConfiguration": null,
  "volumes": []
}

My config are following these posts:

https://www.proud2becloud.com/how-to-setup-a-continuous-deployment-pipeline-on-aws-for-ecs-blue-green-deployments/ https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-ECSbluegreen.html

I have tried to find the solution for this but still nothing work. Any help would be greatly appreciated.

Upvotes: 1

Views: 1086

Answers (1)

Ronan Cunningham
Ronan Cunningham

Reputation: 404

The documentation on this is generally poor.

In your task definition you have: "image": "<IMAGE1_NAME>"

Within your pipeline definition you need a file, specifically named imageDetail.json

It needs to be exactly like the following, with the relevant Docker Image.

{"ImageURI":"???????.dkr.ecr.eu-west-1.amazonaws.com/???/???:????"}

If your pipeline is using ECR as the Source to trigger the pipeline then it creates it for you I think, if not you need to create it for yourself.

For example, In my pipeline I don't use ECR as the source, I compile the code, create and push the image and then produce the imageDetail.json using a CodeBuild project, the output of which is named BuildDockerOutput

            - Name: BlueGreenDeploy
              InputArtifacts:
              - Name: PrepareCodeDeployOutputProd
              - Name: BuildDockerOutput
              Region: !Ref DeployRegion1
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: '1'
                Provider: CodeDeployToECS
              RoleArn: !Sub arn:aws:iam::${ProdAccountId}:role/CrossAccountsDeploymentRole
              Configuration:

                AppSpecTemplateArtifact: PrepareCodeDeployOutputProd
                AppSpecTemplatePath: appspec.json

                ApplicationName: !Ref ApplicationName
                DeploymentGroupName: !Ref ApplicationName
                
                TaskDefinitionTemplateArtifact: PrepareCodeDeployOutputProd
                TaskDefinitionTemplatePath: taskdef.json

                Image1ArtifactName: BuildDockerOutput
                Image1ContainerName: "IMAGE1_NAME"

Artifact BuildDockerOutput is an input to the CodeDeploy Stage and it substitutes the <IMAGE1_NAME> placeholder with value of ImageURI from imageDetail.json.

Note I never specify the file name.

Upvotes: 2

Related Questions