Skip to content

Commit

Permalink
Add checks for environment and image_tag pipeline variables
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnStainsby committed Dec 19, 2024
1 parent fe2ba34 commit 0d19cfa
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
25 changes: 23 additions & 2 deletions codebase-pipelines/buildspec-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,46 @@ phases:
build:
commands:
- set -e

# Check if the specified image tag exists
- |
if ! aws ecr describe-images --repository-name "${REPOSITORY_NAME}" --image-ids "imageTag=${IMAGE_TAG}" > /dev/null 2>&1; then
echo "Error: image tag ${IMAGE_TAG} not found in repository ${REPOSITORY_NAME}"
exit 1
fi
# Check environment exists in config
- |
if [ $(echo $ENV_CONFIG | jq 'has('\"${ENVIRONMENT}\"')') == "false" ]; then
echo "Error: environment ${ENVIRONMENT} not listed in environment config"
exit 1
fi
- task_family="${APPLICATION}-${ENVIRONMENT}-${SERVICE}"
- cluster="${APPLICATION}-${ENVIRONMENT}"
- image_uri="${REPOSITORY_URL}:${IMAGE_TAG}"

# Assume environment role
- account_id=$(echo ${ENV_CONFIG} | jq -c -r .${ENVIRONMENT}.account)
- assumed_role=$(aws sts assume-role --role-arn "arn:aws:iam::${account_id}:role/${APPLICATION}-${ENVIRONMENT}-codebase-pipeline-deploy" --role-session-name "${ENVIRONMENT}-codebase-pipeline-deploy")
- export AWS_ACCESS_KEY_ID=$(echo $assumed_role | jq -r .Credentials.AccessKeyId)
- export AWS_SECRET_ACCESS_KEY=$(echo $assumed_role | jq -r .Credentials.SecretAccessKey)
- export AWS_SESSION_TOKEN=$(echo $assumed_role | jq -r .Credentials.SessionToken)

# Get service name
- service_name=$(aws ecs list-services --cluster ${cluster} | jq -r '.serviceArns[] | select(contains("'${cluster}'-'${SERVICE}'-Service"))' | cut -d '/' -f3)
- service_name=$(aws ecs list-services --cluster "${cluster}" | jq -r '.serviceArns[] | select(contains("'${cluster}'-'${SERVICE}'-Service"))' | cut -d '/' -f3)

# Update task definition
- task_definition=$(aws ecs describe-task-definition --task-definition "${task_family}")
- new_task_definition=$(echo ${task_definition} | jq --arg IMAGE "$image_uri" '.taskDefinition | .containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)')
- new_task_definition=$(echo ${task_definition} | jq '.taskDefinition | .containerDefinitions[0].image = '\"${image_uri}\"' | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)')
- new_task_info=$(aws ecs register-task-definition --cli-input-json "${new_task_definition}")
- new_revision=$(echo ${new_task_info} | jq '.taskDefinition.revision')

# Start deployment
- start=$( date +%s )
- deploy_status="IN_PROGRESS"
- aws ecs update-service --cluster "${cluster}" --service "${service_name}" --task-definition "${task_family}:${new_revision}" > /dev/null 2>&1

# Check deployment status
- |
while [[ "${deploy_status}" == "IN_PROGRESS" || "${deploy_status}" == "PENDING" || "${deploy_status}" == "ROLLBACK_IN_PROGRESS" ]];
Expand All @@ -44,6 +64,7 @@ phases:
exit 1
fi
done
# Check deployment success
- |
if [ "${deploy_status}" != "SUCCESSFUL" ]; then
Expand Down
2 changes: 2 additions & 0 deletions codebase-pipelines/codepipeline.tf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ resource "aws_codepipeline" "codebase_pipeline" {
{ name : "ENVIRONMENT", value : stage.value.name },
{ name : "SERVICE", value : action.value.name },
{ name : "REPOSITORY_URL", value : local.repository_url },
{ name : "REPOSITORY_NAME", value : local.ecr_name },
{ name : "IMAGE_TAG", value : "#{variables.IMAGE_TAG}" }
])
}
Expand Down Expand Up @@ -157,6 +158,7 @@ resource "aws_codepipeline" "manual_release_pipeline" {
{ name : "ENVIRONMENT", value : "#{variables.ENVIRONMENT}" },
{ name : "SERVICE", value : action.value.name },
{ name : "REPOSITORY_URL", value : local.repository_url },
{ name : "REPOSITORY_NAME", value : local.ecr_name },
{ name : "IMAGE_TAG", value : "#{variables.IMAGE_TAG}" }
])
}
Expand Down
6 changes: 6 additions & 0 deletions codebase-pipelines/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ resource "aws_iam_role_policy" "log_access_for_codebuild_deploy" {
policy = data.aws_iam_policy_document.log_access.json
}

resource "aws_iam_role_policy" "ecr_access_for_codebuild_deploy" {
name = "ecr-access"
role = aws_iam_role.codebase_deploy.name
policy = data.aws_iam_policy_document.ecr_access_for_codebase_pipeline.json
}

resource "aws_iam_role_policy" "environment_deploy_role_access_for_codebuild_deploy" {
name = "environment-deploy-role-access"
role = aws_iam_role.codebase_deploy.name
Expand Down
24 changes: 16 additions & 8 deletions codebase-pipelines/tests/unit.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ run "test_iam" {
condition = aws_iam_role_policy.log_access_for_codebuild_deploy.role == "my-app-my-codebase-codebase-pipeline-deploy"
error_message = "Should be: 'my-app-my-codebase-codebase-pipeline-deploy'"
}
assert {
condition = aws_iam_role_policy.ecr_access_for_codebuild_deploy.name == "ecr-access"
error_message = "Should be: 'ecr-access'"
}
assert {
condition = aws_iam_role_policy.ecr_access_for_codebuild_deploy.role == "my-app-my-codebase-codebase-pipeline-deploy"
error_message = "Should be: 'my-app-my-codebase-codebase-pipeline-deploy'"
}
assert {
condition = aws_iam_role_policy.environment_deploy_role_access_for_codebuild_deploy.name == "environment-deploy-role-access"
error_message = "Should be: 'environment-deploy-role-access'"
Expand Down Expand Up @@ -909,7 +917,7 @@ run "test_main_pipeline" {
error_message = "Should be: my-app-my-codebase-codebase-pipeline-deploy"
}
assert {
condition = aws_codepipeline.codebase_pipeline[0].stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"dev\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[0].stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"dev\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down Expand Up @@ -947,7 +955,7 @@ run "test_main_pipeline" {
error_message = "Should be: my-app-my-codebase-codebase-pipeline-deploy"
}
assert {
condition = aws_codepipeline.codebase_pipeline[0].stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"dev\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[0].stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"dev\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down Expand Up @@ -990,7 +998,7 @@ run "test_tagged_pipeline" {
error_message = "Should be: service-1"
}
assert {
condition = aws_codepipeline.codebase_pipeline[1].stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"staging\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[1].stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"staging\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand All @@ -1004,7 +1012,7 @@ run "test_tagged_pipeline" {
error_message = "Should be: service-1"
}
assert {
condition = aws_codepipeline.codebase_pipeline[1].stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"staging\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[1].stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"staging\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down Expand Up @@ -1050,7 +1058,7 @@ run "test_tagged_pipeline" {
error_message = "Should be: service-1"
}
assert {
condition = aws_codepipeline.codebase_pipeline[1].stage[2].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"prod\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[1].stage[2].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"prod\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand All @@ -1064,7 +1072,7 @@ run "test_tagged_pipeline" {
error_message = "Should be: service-1"
}
assert {
condition = aws_codepipeline.codebase_pipeline[1].stage[2].action[2].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"prod\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.codebase_pipeline[1].stage[2].action[2].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"prod\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down Expand Up @@ -1199,7 +1207,7 @@ run "test_manual_release_pipeline" {
error_message = "Should be: my-app-my-codebase-codebase-pipeline-deploy"
}
assert {
condition = aws_codepipeline.manual_release_pipeline.stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"#{variables.ENVIRONMENT}\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.manual_release_pipeline.stage[1].action[0].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"#{variables.ENVIRONMENT}\"},{\"name\":\"SERVICE\",\"value\":\"service-1\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down Expand Up @@ -1237,7 +1245,7 @@ run "test_manual_release_pipeline" {
error_message = "Should be: my-app-my-codebase-codebase-pipeline-deploy"
}
assert {
condition = aws_codepipeline.manual_release_pipeline.stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"#{variables.ENVIRONMENT}\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
condition = aws_codepipeline.manual_release_pipeline.stage[1].action[1].configuration.EnvironmentVariables == "[{\"name\":\"APPLICATION\",\"value\":\"my-app\"},{\"name\":\"ENVIRONMENT\",\"value\":\"#{variables.ENVIRONMENT}\"},{\"name\":\"SERVICE\",\"value\":\"service-2\"},{\"name\":\"REPOSITORY_URL\",\"value\":\"${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/my-app/my-codebase\"},{\"name\":\"REPOSITORY_NAME\",\"value\":\"my-app/my-codebase\"},{\"name\":\"IMAGE_TAG\",\"value\":\"#{variables.IMAGE_TAG}\"}]"
error_message = "Configuration environment variables incorrect"
}
assert {
Expand Down

0 comments on commit 0d19cfa

Please sign in to comment.