By using AWS re:Post, you agree to the Terms of Use

Using Elastic Beanstalk - Docker Platform with ECR - Specifying a tag via environment variable

0

Hi, I am trying to develop a CI/CD process, using Beanstalk's Docker platform with ECR. Code Pipeline performs the builds and manages ECR Tags & Promotions. Terraform manages the infrastructure.

I am looking for an approach that allows us to use the same Dockerfile/Dockerrun.aws.json in production & non-production environments, despite wanting different tags of the same image deployed.. Perhaps from different repositories (repo_name_PROD vs repo_name_DEV ).

Producing and moving Beanstalk bundles that only differ in a TAG feels unnecessary. the idea of dynamically changing Dockerfiles using the deployment process also seems fragile.

What I was exploring was using a simple Environment variable: change what tag (comitHash) of an image should be based on a Beanstalk environment variable.

FROM 00000000000.dkr.ecr.us-east-1.amazonaws.com/repoName:${TAG}
ADD entrypoint.sh /
EXPOSE 8080 8787 9990
ENTRYPOINT [ "/entrypoint.sh" ]

Where TAG is the Git hash of the code repository from which the artifact was produced. CodeBuild has built the code and tagged the docker image.

I understand that Docker supports this:

ARG TAG
FROM 00000000000.dkr.ecr.us-east-1.amazonaws.com/repo_name:${TAG}
ADD entrypoint.sh /
EXPOSE 8080 8787 9990
ENTRYPOINT [ "/entrypoint.sh" ]

but requires building the image like this:

docker build --build-arg GIT_TAG=SOME_TAG .

Am I correct in assuming this wil not work with the docker platform? I do not believe the EB Docker platform exposes a way to specify the build-arg.

What is standard practice for managing tagged docker images in Beanstalk.

I am a little leery of the latest tag.. as a poorly timed auto scaling event could pull an update before it should be deployed: that just does not work in my case.

Updating my Dockerfile dufing deployment (via sed ) seems like asking for trouble.

1 Answer
0

Hello there,

You can use CodeBuild to auto modify the Dockerrun.aws.json to reference to the latest image tag dynamically. In your CodeBuild project buildspec.yml, you can utilize the predefined CODEBUILD_RESOLVED_SOURCE_VERSION envrionment variable to retrieve commit ID, passing it as image tag, for example:

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/web
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG

artifacts:
  files:
    - 'Dockerrun.aws.json'

$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) gives you the first seven characters of the Git commit ID of the source.

In Dockerrun.aws.json, you can define something like below:

{
  "containerDefinitions": [
    {
      "name": "web",
      "image": "{$AWS_ACCOUNT_ID}.dkr.ecr.{$AWS_DEFAULT_REGION}.amazonaws.com/web:{$IMAGE_TAG}",
      "hostname": "web",
      "essential": true,
      "memory": 1024,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ]
    }
  ]
  ...
}

CodeBuild and CopdePipeline will update image tag and Dockerrun.aws.json dynamically whenever you push code change to source repo.

SUPPORT ENGINEER
answered 8 months ago
  • Zhiyuan_L, Thank you for this information.

    There is one aspect on which I am not clear. probably because I am learning CodeBuild: I understand from your response that CodeBuild will do the transformation I am after. so: Creates the Dockerrun.aws.json and I would place Dockerrun.aws.json in the beanstalk artifact? I have a Zip file with Dockerfile/ebextensions ect,

    In code build how would I use the Dockerrun.aws.json that was produced?

    Just making sure I am connecting the dots here.

    I'll look at the documentation to find where it discusses these types of transformations!

    Thanks!

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions