Search code examples
amazon-web-servicesjenkinscontinuous-integrationaws-cloudformationamazon-ecs

How to deploy a specific artifact version to AWS ECS without hard coding its id in Cloudformation template


In a CI pipeline based on Jenkins, Docker and Artifactory, my-component is built, containerised and then published to Artifactory with the following id:

docker.artifacts.mycompany.com/my-component:{Unix timestamp}

The last stage of Jenkins then also tags that artifact with a "latest" tag:

docker.artifacts.mycompany.com/my-component:latest

Through this Cloudformation template, this tag allows AWS ECS to pick up the artifact (tagged "latest") and deploy it:

Parameters:
  SourceInstanceRole:
    Type: String
    Description: The IAM role that the my-component instance will use
    Default: Jenken-Automation
  ImageRepository:
    Type: String
    Description: The name of the Docker repository which holds my-component Docker images
    Default: docker.artifacts.mycompany.com
  ImageName:
    Type: String
    Description: The name of the Docker image for my-component
    Default: my-component
  ImageVersion:
    Type: String
    Description: The version tag of my-component docker image in Artifactory
    Default: latest


MyComponentTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Volumes:
      - Name: no-volume
      ContainerDefinitions:
      - Name: !Ref ContainerName
        Essential: true
        Memory: !Ref Memory
        MemoryReservation: !Ref MemoryReservation
        Image: !Sub ${ImageRepository}/${ImageName}:${ImageVersion}

I need to move away from this approach as I want to be able to specify any version of the artifact for deployment - not the "latest". My question is:

How can I trigger the deployment of a specific artifact version to ECS without hard coding the image version in the Cloudformation template?

e.g.: docker.artifacts.mycompany.com/my-component:1500436061


Solution

  • You need to use parameter overrides to programmatically change the default values hardcoded in your CloudFormation template.

    So for example perhaps your Jenkins build has a bash script that uses the AWS CLI to deploy the CF template using a command like:

    aws cloudformation deploy --template-file mystack.yml --stack-name mystack
    

    You can specify an override for the ImageVersion variable like this:

    aws cloudformation deploy --template-file mystack.yml --stack-name mystack --parameter-overrides ImageVersion={Unix timestamp}
    

    Here are the docs for parameter overrides using the CLI: http://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html

    And if you are using the AWS SDK for any language it will also have the parameter overrides ability. Basically, whatever mechanism you are using for programmatically deploying the CF template will also have a way to specify a parameter override that changes the default value to one that is custom for that specific release.