Update the cloudformation template in cloudformation/ecr.yml
and define a policy for your ECR repository:
---
AWSTemplateFormatVersion: 2010-09-09
Description: ECR repository for '...'
Parameters:
RepositoryName:
Type: String
Description: 'Name of the ECR repository'
Resources:
Repository:
Type: 'AWS::ECR::Repository'
Properties:
RepositoryName: !Ref RepositoryName
RepositoryPolicyText:
Version: "2012-10-17"
Statement:
- Sid: AllowDockerPull
Effect: Allow
Principal:
AWS:
- "arn:aws:iam::AWS_ACCOUNT1:root"
- "arn:aws:iam::AWS_ACCOUNT2:root"
Action:
- "ecr:GetDownloadUrlForLayer"
- "ecr:BatchGetImage"
- "ecr:BatchCheckLayerAvailability"
Make sure to replace AWS_ACCOUNT1
, AWS_ACCOUNT2
, etc. with the correct account numbers.
Update the Cloudformation stack with the following command in the ci AWS account
AWS_PROFILE=myorg-ci make ecr
Create a new Cloudformation template cloudformation/deployment-role.yml
with the following content:
---
AWSTemplateFormatVersion: 2010-09-09
Description: Deployment IAM role for '...'
Parameters:
CiAwsAccountId:
Type: String
AllowedPattern: '^[0-9]*$'
Description: ID of the CI AWS account
Resources:
RoleAdministrator:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref AWS::StackName
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${CiAwsAccountId}:root'
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
Enhance your project Makefile
in the project directory with the following content:
.PHONY: deployment-role
deployment-role: guard-STAGE
aws cloudformation deploy \
--no-fail-on-empty-changeset \
--template-file cloudformation/deployment-role.yml \
--stack-name $(SERVICE)-$(STAGE)-deployment-role \
--parameter-overrides CiAwsAccountId=$(CI_AWS_ACCOUNT_ID) \
--region $(AWS_REGION)
Create the Cloudformation stack with the following command in the app-staging AWS account
AWS_PROFILE=myorg-app-staging make deployment-role STAGE=dev
Create a new file assume-role.sh
in your project:
#!/usr/bin/env bash -e
if [ $# -le 2 ]; then
echo "Error: invalid number of parameters"
exit 1
fi
ROLE_TO_ASSUME=$1
shift;
ROLE=(`aws sts assume-role --role-arn "${ROLE_TO_ASSUME}" --role-session-name "${ROLE_TO_ASSUME}-$(date +%s)" \
--output text --query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]'`)
export AWS_ACCESS_KEY_ID="${ROLE[0]}"
export AWS_SECRET_ACCESS_KEY="${ROLE[1]}"
export AWS_SECURITY_TOKEN="${ROLE[2]}"
export AWS_SESSION_TOKEN="${ROLE[2]}"
exec $@
Set the executable bit on the file:
chmod +x ./assume-role.sh
Change your buildspec_deploy.yml
as follows:
version: 0.2
env:
variables:
ROLE_NAME: "java-docker-aws-example-fstehle-dev-deployment-role"
phases:
install:
runtime-versions:
java: openjdk8
docker: 18
commands:
- pip install awsebcli
build:
commands:
- echo "Setting up the database and the Elastic Beanstalk app"
- ./assume-role.sh arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ROLE_NAME} make database app STAGE=dev
- echo "Deploying Docker container to the Elastic Beanstalk app"
- ./assume-role.sh arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ROLE_NAME} make deploy STAGE=dev
Make sure to commit and push everything to the repository:
git add buildspec_deploy.yml
git commit -m 'Enhance pipeline by setting up the database and the Elastic Beanstalk app'
Then push to your branch
git push ...
Log in to the AWS Console, switch to the CI account and trigger your pipeline.