Skip to content

Commit

Permalink
CI/CD Pipeline: Add sync mechanism and publish SSM parameters (fluent#22
Browse files Browse the repository at this point in the history
)

Add sync mechanism and publish SSM parameters
  • Loading branch information
hossain-rayhan authored Jan 17, 2020
1 parent e295703 commit 0dfbeb0
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 24 deletions.
1 change: 1 addition & 0 deletions buildspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ phases:
- docker images

# Push the image to ECR in the same account and same region the pipeline is hosted.
- docker tag amazon/aws-for-fluent-bit:latest amazon/aws-for-fluent-bit-test:latest
- ecs-cli push amazon/aws-for-fluent-bit-test:latest
artifacts:
files:
Expand Down
4 changes: 3 additions & 1 deletion buildspec_publish_ecr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ phases:
export AWS_SESSION_TOKEN=
fi
# Assume role to verify, get the credentials, and set them as environment variables
# Assume role to verify, get the credentials, and set them as environment variables.
# Verification should be done using the credentials from a different account. It ensures that
# the images we published are public and accessible from any account.
- CREDS=`aws sts assume-role --role-arn ${VERIFY_ROLE_ARN} --role-session-name ${REGION_TO_PUSH} --region ${REGION_TO_PUSH}`
- export AWS_ACCESS_KEY_ID=`echo $CREDS | jq -r .Credentials.AccessKeyId`
- export AWS_SECRET_ACCESS_KEY=`echo $CREDS | jq -r .Credentials.SecretAccessKey`
Expand Down
24 changes: 24 additions & 0 deletions buildspec_publish_ssm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 0.2
phases:
install:
runtime-versions:
golang: 1.12
pre_build:
commands:
- echo Publish SSM parameters
build:
commands:
- './scripts/publish_test.sh cicd-publish-ssm ${AWS_REGION}'

# Assume role to verify, get the credentials, and set them as environment variables.
# Verification should be done using the credentials from a different account. It ensures that
# the ssm parameters we published are public and accessible from any account.
- CREDS=`aws sts assume-role --role-arn ${VERIFY_ROLE_ARN} --role-session-name ${AWS_REGION} --region ${AWS_REGION}`
- export AWS_ACCESS_KEY_ID=`echo $CREDS | jq -r .Credentials.AccessKeyId`
- export AWS_SECRET_ACCESS_KEY=`echo $CREDS | jq -r .Credentials.SecretAccessKey`
- export AWS_SESSION_TOKEN=`echo $CREDS | jq -r .Credentials.SessionToken`

- './scripts/publish_test.sh cicd-verify-ssm ${AWS_REGION}'
artifacts:
files:
- '**/*'
26 changes: 26 additions & 0 deletions buildspec_sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: 0.2
phases:
install:
runtime-versions:
golang: 1.12
pre_build:
commands:
- echo Sync latest image from Dockerhub
build:
commands:
- './scripts/publish_test.sh cicd-publish ${AWS_REGION}'

# Assume role to verify, get the credentials, and set them as environment variables.
# Verification should be done using the credentials from a different account. It ensures that
# the images we published are public and accessible from any account.
- CREDS=`aws sts assume-role --role-arn ${VERIFY_ROLE_ARN} --role-session-name ${AWS_REGION} --region ${AWS_REGION}`
- export AWS_ACCESS_KEY_ID=`echo $CREDS | jq -r .Credentials.AccessKeyId`
- export AWS_SECRET_ACCESS_KEY=`echo $CREDS | jq -r .Credentials.SecretAccessKey`
- export AWS_SESSION_TOKEN=`echo $CREDS | jq -r .Credentials.SessionToken`

# Verify from the verification account
- './scripts/publish_test.sh cicd-verify ${AWS_REGION}'
- './scripts/publish_test.sh cicd-verify-ssm ${AWS_REGION}'
artifacts:
files:
- '**/*'
137 changes: 114 additions & 23 deletions scripts/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

set -xeuo pipefail

scripts=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
scripts=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
cd "${scripts}"

IMAGE_SHA_MATCHED="FALSE"
Expand Down Expand Up @@ -77,7 +77,7 @@ publish_to_docker_hub() {
# Logout when the script exits
trap cleanup EXIT
cleanup() {
docker logout
docker logout
}

# login to DockerHub
Expand All @@ -99,11 +99,11 @@ publish_to_docker_hub() {

publish_ssm() {
aws ssm put-parameter --name /aws/service/aws-for-fluent-bit/${AWS_FOR_FLUENT_BIT_VERSION} --overwrite \
--description 'Regional Amazon ECR Image URI for the latest AWS for Fluent Bit Docker Image' \
--type String --region ${1} --value ${2}:${AWS_FOR_FLUENT_BIT_VERSION}
--description 'Regional Amazon ECR Image URI for the latest AWS for Fluent Bit Docker Image' \
--type String --region ${1} --value ${2}:${AWS_FOR_FLUENT_BIT_VERSION}
aws ssm put-parameter --name /aws/service/aws-for-fluent-bit/latest --overwrite \
--description 'Regional Amazon ECR Image URI for the latest AWS for Fluent Bit Docker Image' \
--type String --region ${1} --value ${2}:latest
--description 'Regional Amazon ECR Image URI for the latest AWS for Fluent Bit Docker Image' \
--type String --region ${1} --value ${2}:latest
}

rollback_ssm() {
Expand All @@ -112,7 +112,7 @@ rollback_ssm() {

check_parameter() {
repo_uri=$(aws ssm get-parameter --name /aws/service/aws-for-fluent-bit/${2} --region ${1} --query 'Parameter.Value')
IFS='.' read -r -a array <<< "$repo_uri"
IFS='.' read -r -a array <<<"$repo_uri"
region="${array[3]}"
if [ "${1}" != "${region}" ]; then
echo "${1}: Region found in repo URI does not match SSM Parameter region: ${repo_uri}"
Expand All @@ -123,6 +123,39 @@ check_parameter() {
pull_ecr $repo_uri $region
}

sync_latest_image() {
region=${1}
account_id=${2}
sha1=$(docker pull amazon/aws-for-fluent-bit:latest | grep sha256: | cut -f 3 -d :)

endpoint='amazonaws.com'
if [ "${1}" = "cn-north-1" ] || [ "${1}" = "cn-northwest-1" ]; then
endpoint=${endpoint}.cn
fi

repoList=$(aws ecr describe-repositories --region ${region})
repoName=$(echo $repoList | jq .repositories[0].repositoryName)
if [ "$repoName" = '"aws-for-fluent-bit"' ]; then
pull_ecr ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:latest ${region}
sha2=$(docker inspect --format='{{index .RepoDigests 0}}' ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:latest)
else
sha2='repo_not_found'
fi

docker images
match_two_sha $sha1 $sha2

if [ "$IMAGE_SHA_MATCHED" = "FALSE" ]; then
publish_ecr ${region} ${account_id}
fi

ssm_parameters=$(aws ssm get-parameters --names "/aws/service/aws-for-fluent-bit/${AWS_FOR_FLUENT_BIT_VERSION}" --region ${region})
invalid_parameter=$(echo $ssm_parameters | jq .InvalidParameters[0])
if [ "$invalid_parameter" != 'null' ]; then
publish_ssm ${region} ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit
fi
}

verify_ssm() {
check_parameter ${1} latest
check_parameter ${1} ${AWS_FOR_FLUENT_BIT_VERSION}
Expand All @@ -138,7 +171,7 @@ pull_ecr() {
}

make_repo_public() {
aws ecr set-repository-policy --repository-name aws-for-fluent-bit --policy-text file://public_repo_policy.json --region ${1}
aws ecr set-repository-policy --repository-name aws-for-fluent-bit --policy-text file://public_repo_policy.json --region ${1}
}

publish_ecr() {
Expand All @@ -152,12 +185,18 @@ publish_ecr() {
verify_ecr() {
region=${1}
account_id=${2}
pull_ecr ${account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit:latest ${region}
pull_ecr ${account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit:${AWS_FOR_FLUENT_BIT_VERSION} ${region}

# Get the image SHA's
sha1=$(docker inspect --format='{{index .RepoDigests 0}}' ${account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit:latest)
sha2=$(docker inspect --format='{{index .RepoDigests 0}}' ${account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit:${AWS_FOR_FLUENT_BIT_VERSION})

endpoint='amazonaws.com'
if [ "${1}" = "cn-north-1" ] || [ "${1}" = "cn-northwest-1" ]; then
endpoint=${endpoint}.cn
fi

pull_ecr ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:latest ${region}
pull_ecr ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:${AWS_FOR_FLUENT_BIT_VERSION} ${region}

#Verification logic matching the image SHA
sha1=$(docker inspect --format='{{index .RepoDigests 0}}' ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:latest)
sha2=$(docker inspect --format='{{index .RepoDigests 0}}' ${account_id}.dkr.ecr.${region}.${endpoint}/aws-for-fluent-bit:${AWS_FOR_FLUENT_BIT_VERSION})

verify_sha $sha1 $sha2
}
Expand Down Expand Up @@ -188,7 +227,7 @@ verify_sha() {
match_two_sha() {
sha1=${1}
sha2=${2}

# Get the last 64 chars of the SHA string
last64_1=$(echo $sha1 | egrep -o '.{1,64}$')
last64_2=$(echo $sha2 | egrep -o '.{1,64}$')
Expand Down Expand Up @@ -274,7 +313,6 @@ if [ "${1}" = "verify" ]; then
fi
fi


if [ "${1}" = "publish-ssm" ]; then
if [ "${2}" = "aws" ]; then
for region in ${classic_regions}; do
Expand Down Expand Up @@ -331,7 +369,6 @@ if [ "${1}" = "verify-ssm" ]; then
fi
fi


if [ "${1}" = "rollback-ssm" ]; then
if [ "${2}" = "aws" ]; then
for region in ${classic_regions}; do
Expand Down Expand Up @@ -365,14 +402,18 @@ fi
if [ "${1}" = "cicd-publish" ]; then
if [ "${2}" = "dockerhub" ]; then
publish_to_docker_hub amazon/aws-for-fluent-bit:latest amazon/aws-for-fluent-bit:${AWS_FOR_FLUENT_BIT_VERSION}
elif [ "${2}" = "aws-us-gov" ]; then
elif [ "${2}" = "us-gov-east-1" ] || [ "${2}" = "us-gov-west-1" ]; then
for region in ${gov_regions}; do
gov_cloud_sync ${region} ${gov_regions_account_id}
sync_latest_image ${region} ${gov_regions_account_id}
done
elif [ "${2}" = "cn-north-1" ] || [ "${2}" = "cn-northwest-1" ]; then
for region in ${cn_regions}; do
sync_latest_image ${region} ${cn_regions_account_id}
done
elif [ "${2}" = "${bahrain_region}" ]; then
sync_latest_image ${bahrain_region} ${bahrain_account_id}
elif [ "${2}" = "${hongkong_region}" ]; then
publish_ecr ${hongkong_region} ${hongkong_account_id}
elif [ "${2}" = "${bahrain_region}" ]; then
publish_ecr ${bahrain_region} ${bahrain_account_id}
else
publish_ecr "${2}" ${classic_regions_account_id}
fi
Expand All @@ -382,11 +423,61 @@ fi
if [ "${1}" = "cicd-verify" ]; then
if [ "${2}" = "dockerhub" ]; then
verify_dockerhub
elif [ "${2}" = "${hongkong_region}" ]; then
verify_ecr ${hongkong_region} ${hongkong_account_id}
elif [ "${2}" = "us-gov-east-1" ] || [ "${2}" = "us-gov-west-1" ]; then
for region in ${gov_regions}; do
verify_ecr ${region} ${gov_regions_account_id}
done
elif [ "${2}" = "cn-north-1" ] || [ "${2}" = "cn-northwest-1" ]; then
for region in ${cn_regions}; do
verify_ecr ${region} ${cn_regions_account_id}
done
elif [ "${2}" = "${bahrain_region}" ]; then
verify_ecr ${bahrain_region} ${bahrain_account_id}
elif [ "${2}" = "${hongkong_region}" ]; then
verify_ecr ${hongkong_region} ${hongkong_account_id}
else
verify_ecr "${2}" ${classic_regions_account_id}
fi
fi

# Publish SSM parameters
if [ "${1}" = "cicd-publish-ssm" ]; then
if [ "${2}" = "us-gov-east-1" ] || [ "${2}" = "us-gov-west-1" ]; then
for region in ${gov_regions}; do
publish_ssm ${region} ${gov_regions_account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit
done
elif [ "${2}" = "cn-north-1" ] || [ "${2}" = "cn-northwest-1" ]; then
for region in ${cn_regions}; do
publish_ssm ${region} ${cn_regions_account_id}.dkr.ecr.${region}.amazonaws.com.cn/aws-for-fluent-bit
done
elif [ "${2}" = "${bahrain_region}" ]; then
publish_ssm ${bahrain_region} ${bahrain_account_id}.dkr.ecr.${bahrain_region}.amazonaws.com/aws-for-fluent-bit
elif [ "${2}" = "${hongkong_region}" ]; then
publish_ssm ${hongkong_region} ${hongkong_account_id}.dkr.ecr.${hongkong_region}.amazonaws.com/aws-for-fluent-bit
else
for region in ${classic_regions}; do
publish_ssm ${region} ${classic_regions_account_id}.dkr.ecr.${region}.amazonaws.com/aws-for-fluent-bit
done
fi
fi

# Verify SSM parameters
if [ "${1}" = "cicd-verify-ssm" ]; then
if [ "${2}" = "us-gov-east-1" ] || [ "${2}" = "us-gov-west-1" ]; then
for region in ${gov_regions}; do
verify_ssm ${region}
done
elif [ "${2}" = "cn-north-1" ] || [ "${2}" = "cn-northwest-1" ]; then
for region in ${cn_regions}; do
verify_ssm ${region}
done
elif [ "${2}" = "${bahrain_region}" ]; then
verify_ssm ${bahrain_region}
elif [ "${2}" = "${hongkong_region}" ]; then
verify_ssm ${hongkong_region}
else
for region in ${classic_regions}; do
verify_ssm ${region}
done
fi
fi

0 comments on commit 0dfbeb0

Please sign in to comment.