Using CodePipeline to Deploy ElasticBeanstalk application in another AWS account

Viewed 841

We have a setup with different AWS accounts for each environment(dev, test, prod) and then a shared build account which has a AWS CodePipeline that deploys into each of these environment by assuming a role in dev, test, prod.

This works fine for our Serverless applications using a Codebuild script.

Can we do something similar for the Elastic Beanstalk application that uses the deploy action provider? Or what is the best approach for Elastic Beanstalk

3 Answers

We do this by using a CodeBuild job specified in each of the stage accounts (dev, test, prod) that uses the AWS CLI to deploy the CodePipeline artifact (available as CODEBUILD_SOURCE_VERSION in your build job's environment variables) to Elastic Beanstalk. We run this job as part of a CodePipeline in our shared build account.

These are the AWS CLI commands the CodeBuild deploy job runs:

aws elasticbeanstalk create-application-version --application-name ... --version-label ... --source-bundle S3Bucket="codepipeline-artifacts-us-east-1-123456789012",S3Key="application/deployable/XXXXXXX"
aws elasticbeanstalk update-environment --environment-name ... --version-label ...

You can specify a CodeBuild job from another account in CodePipeline using the strategy outlined here: https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html. It involves setting up cross-account access to the role_arn used for the CodeBuild deploy job and a customer managed KMS key for the pipeline (with a cross-account access policy).

One deficiency with this approach is that the CodeBuild deploy job will complete as soon as the deployment starts and not wait until the ElasticBeanstalk deployment succeeds or fails, as the native CodePipeline EB deploy action does. You should be able to call aws elasticbeanstalk describe-environments in a loop from the job to replicate this behavior, but I have not yet attempted this. (Sample script here: https://blog.cyplo.net/posts/2018/04/wait-for-beanstalk/)

I have found the solution to cross account deployment of application to elastic beanstalk in another aws account using aws cdk.

As aws cdk do not have deploy to elastic beanstalk action feature yet so we have to implement it manually by implementing IAction interface

You can find complete working CDK app in my git repo

https://github.com/dhirajkhodade/CDKDotNetWebAppEbPipeline

We ended up solving it this way using CodeBuild:

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.8
    commands:
      - pip install awsebcli --upgrade
  pre_build:
    commands:
      - CRED=`aws sts assume-role --role-arn $assume_role --role-session-name codebuild-deployment-$environment`
      - export AWS_ACCESS_KEY_ID=`node -pe 'JSON.parse(process.argv[1]).Credentials.AccessKeyId' "$CRED"`
      - export AWS_SECRET_ACCESS_KEY=`node -pe 'JSON.parse(process.argv[1]).Credentials.SecretAccessKey' "$CRED"`
      - export AWS_SESSION_TOKEN=`node -pe 'JSON.parse(process.argv[1]).Credentials.SessionToken' "$CRED"`
      - export AWS_EXPIRATION=`node -pe 'JSON.parse(process.argv[1]).Credentials.Expiration' "$CRED"`
      - echo $(aws sts get-caller-identity)
  build:
    commands:
      - eb --version
      - eb init <project-name> --platform "Node.js running on 64bit Amazon Linux" --region $AWS_DEFAULT_REGION
      - eb deploy

Using the aws-cli to assume the role we needed and then using eb-cli to do the actual deployment. Not sure if this is the best way, but it works. We are considering moving to another CI/CD tool which is more flexi

Related