Deploying Fargate
Just some notes on the process. This will show how to deploy both a Staging build and then Production.
Staging
Staging is done by TravisCI after all tests pass
Here is the gist of it the deploy step calls to a bash file.
deploy:
skip_cleanup: true
provider: script
script: bash deploy/travis_deploy.sh
on:
branch: mainline
Then
#!/usr/bin/env bash
# Bail out on first error
set -e
## Get the directory of the build script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
## Get the current git commit sha
HASH=$(git rev-parse HEAD)
## Get any secret files
aws s3 cp s3://foo/environments/$STACK_ENV_FILE $DIR/app/packaged/.env
##we only want non-dev vendors
composer config -g github-oauth.github.com $GITHUB_TOKEN && composer install --no-dev
echo "Region $STACK_AWS_REGION is the target region"
eval $(aws ecr get-login --no-include-email --region $STACK_AWS_REGION)
echo "Tagging images $STACK_APP_NAME"
docker build --pull -t $STACK_APP_NAME .
docker tag $STACK_APP_NAME:latest 1111111111.dkr.ecr.$STACK_AWS_REGION.amazonaws.com/$STACK_APP_NAME:latest
echo "Pushing up image $STACK_APP_NAME:latest"
docker push 1111111111.dkr.ecr.us-east-1.amazonaws.com/$STACK_APP_NAME:latest
## Now Run again for Production WILL COME BACK TO THIS IN A MOMENT
## if production set???
if [[ "$STACK_ENV_FILE_PRODUCTION" ]]; then
echo "Running Production build"
aws s3 cp s3://foo/environments/$STACK_ENV_FILE_PRODUCTION $DIR/app/packaged/.env
echo "Building Production Image"
docker build --pull -t $STACK_APP_NAME .
docker tag $STACK_APP_NAME:latest 1111111111.dkr.ecr.us-east-1.amazonaws.com/$STACK_APP_NAME:production_$HASH
echo "Pushing up production image using has production_$HASH"
docker push 1111111111.dkr.ecr.us-east-1.amazonaws.com/$STACK_APP_NAME:production_$HASH
fi
So Staging will build and push right to the AWS ECR which means Fargate by default will get the Latest tagged image since the TaskDefinition says so. So staging is done. Next task will run this one.
Production
This we want to happen by choice not by Travis. So you can see the step in Travis STACK_ENV_FILE_PRODUCTION
that looks for an environment variable and if true it will push the same working image but with it’s own secrets to ECR but with the tag production_GIT_HASH
Then we ready we have a UI to push it BUT really it is just CloudFormation that updates the TaskDefinition using the build in Params to make it reference this HASH. This can be done pretty easily with Python, PHP etc and the AWS SDK that allows you to update CloudFormation and the Parameter that then fills in the TaskDefinition Field and updates it, from there the next time the Production Fargate runs it runs that latest version.
Example Task Definition:
"TaskDefinition": {
"Type": "AWS::ECS::TaskDefinition",
"Properties": {
"ExecutionRoleArn": "",
"Memory": 250,
"NetworkMode": "bridge",
"TaskRoleArn": "arn:aws:iam::364215618558:role/foo",
"ContainerDefinitions": [{
"Name": {
"Fn::Sub": "${AppName}-${AppEnv}"
},
"Image": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${AppName}:${ProductionTag}"
},
"PortMappings": [{
"ContainerPort": 80,
"HostPort": {
"Ref": "AppPort"
}
},
{
"ContainerPort": 443,
"HostPort": {
"Ref": "AppPortSSL"
}
}
],
"Memory": 250,
"MountPoints": [{
"SourceVolume": "shared",
"ContainerPath": "/opt/shared"
}]
}],
"Volumes": [{
"Name": "shared",
"Host": {
"SourcePath": "/opt/shared"
}
}]
},
"DependsOn": [
"ECR"
]
},
So when I update this I can just update the ProductionTag
and this will take effect.
comments powered by Disqus