Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to create service with update_service #229

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2668e63
Add functionality to create service if not created with ECS deployment
marboledacci Dec 3, 2024
30a24f7
Fix syntax errors
marboledacci Dec 3, 2024
141d071
Temporarly remove tear down of ec2 for testgin
marboledacci Dec 3, 2024
a487a80
Add test
marboledacci Dec 3, 2024
7b8841d
Fix test
marboledacci Dec 3, 2024
d3a5aa9
fix test
marboledacci Dec 3, 2024
c186c4e
fix test
marboledacci Dec 3, 2024
97c6e75
Fix tests
marboledacci Dec 3, 2024
0759833
Update test
marboledacci Dec 3, 2024
fe5fa2d
Update test auth
marboledacci Dec 3, 2024
8430522
Update test
marboledacci Dec 3, 2024
f513da5
Update command
marboledacci Dec 3, 2024
d8b08d8
Update tests to make them more reliable
marboledacci Dec 4, 2024
9b4d9a0
Delete service after creation
marboledacci Dec 4, 2024
3af45f9
Update test structure and fix update_service script
marboledacci Dec 4, 2024
255bec2
Update profile in test
marboledacci Dec 4, 2024
3a7b0fb
Add debug to create service
marboledacci Dec 4, 2024
213e14d
Add more debug
marboledacci Dec 4, 2024
cd2458f
Fix linter
marboledacci Dec 4, 2024
4d2e7ba
Ignore healthcheck
marboledacci Dec 4, 2024
cd837c3
Add more debug
marboledacci Dec 4, 2024
23fcc1e
Remove non related tests temp
marboledacci Dec 4, 2024
96bbe1b
Fix shell
marboledacci Dec 4, 2024
ec10dc4
Manually install terraform
marboledacci Dec 5, 2024
83f773b
Fix orb name
marboledacci Dec 5, 2024
765cdc0
Update how task definition is get
marboledacci Dec 5, 2024
9a3b21d
Restore tests
marboledacci Dec 5, 2024
e9cc80a
Publish dev version
marboledacci Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: 2.1
setup: true
orbs:
orb-tools: circleci/orb-tools@12.0
shellcheck: circleci/shellcheck@3.1
orb-tools: circleci/orb-tools@12.2
shellcheck: circleci/shellcheck@3.2

filters: &filters
tags:
Expand All @@ -19,6 +19,13 @@ workflows:
filters: *filters
- shellcheck/check:
filters: *filters
- orb-tools/publish:
orb_name: circleci/aws-ecs
vcs_type: << pipeline.project.type >>
pub_type: dev
context: orb-publisher
requires: [orb-tools/lint, orb-tools/review, orb-tools/pack, shellcheck/check]
filters: *filters
- orb-tools/continue:
orb_name: aws-ecs
pipeline_number: << pipeline.number >>
Expand Down
44 changes: 41 additions & 3 deletions .circleci/test-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
version: 2.1
orbs:
orb-tools: circleci/orb-tools@12.1
aws-cli: circleci/aws-cli@4.1
orb-tools: circleci/orb-tools@12.2
aws-cli: circleci/aws-cli@5.1.1
jq: circleci/[email protected]
aws-ecs: {}
terraform: circleci/[email protected]
filters: &filters
tags:
only: /.*/
Expand Down Expand Up @@ -191,6 +192,37 @@ jobs:
cd << parameters.terraform-config-dir >>
terraform apply -input=false -auto-approve tfplan
set +x
test-service-create:
docker:
- image: cimg/python:3.10.4
shell: bash -eox pipefail
steps:
- checkout
- terraform/install
- aws-cli/setup:
profile_name: profile-create
role_arn: "arn:aws:iam::122211685980:role/CPE_ECS_OIDC_TEST"
- run: |
cd tests/terraform_setup/ec2
terraform init -backend-config="profile=profile-create"
TG_ARN=$(terraform output -raw target_group_arn)
echo $TG_ARN
echo "export TARGET_GROUP_ARN=$TG_ARN" >> $BASH_ENV
- aws-ecs/update_service:
family: ecs-orb-ec2-1-family
cluster: ecs-orb-ec2-1-cluster
create_service: true
skip_task_definition_registration: true
service_name: test-create
desired_count: "2"
target_group: $TARGET_GROUP_ARN
container_name: ecs-orb-ec2-1-service
container_port: "80"
region: us-west-2
profile_name: profile-create
- run: |
aws ecs update-service --cluster ecs-orb-ec2-1-cluster --service test-create --desired-count 0 --region us-west-2 --profile profile-create
aws ecs delete-service --cluster ecs-orb-ec2-1-cluster --service test-create --region us-west-2 --profile profile-create --force
test-service-update:
docker:
- image: cimg/python:3.10.4
Expand Down Expand Up @@ -439,7 +471,7 @@ workflows:
aws-resource-name-prefix: ${AWS_RESOURCE_NAME_PREFIX_FARGATE}
terraform-config-dir: "tests/terraform_setup/fargate"
context: [CPE-OIDC]
role_arn: "arn:aws:iam::122211685980:role/CPE_ECS_OIDC_TEST"
role_arn: "arn:aws:iam::122211685980:role/CPE_ECS_OIDC_TEST"
- build-test-app:
name: fargate_build-test-app
docker-image-namespace: "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
Expand Down Expand Up @@ -551,6 +583,11 @@ workflows:
terraform-config-dir: "tests/terraform_setup/ec2"
context: [CPE-OIDC]
role_arn: "arn:aws:iam::122211685980:role/CPE_ECS_OIDC_TEST"
- test-service-create:
name: ec2_create_service
filters: *filters
requires:
- ec2_set-up-test-env
- set-up-run_task-test:
name: ec2_set-up-run_task-test
filters: *filters
Expand Down Expand Up @@ -579,6 +616,7 @@ workflows:
filters: *filters
requires:
- ec2_run_task-test
- ec2_create_service
family_name: ${AWS_RESOURCE_NAME_PREFIX_EC2}-sleep360
context: [CPE-OIDC]
role_arn: "arn:aws:iam::122211685980:role/CPE_ECS_OIDC_TEST"
Expand Down
72 changes: 70 additions & 2 deletions src/commands/update_service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,66 @@ parameters:
If not specified, the value configured in the deployment group is used as the default.
type: string
default: ''
create_service:
type: boolean
description: |
Create the service if it does not exist already.
Only works with ECS deployment controller.
Default false.
default: false
desired_count:
description: |
The desired number of tasks to run. If empty it would keep the existing count.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
subnets:
description: |
Comma separated list of subnet ids for the service when it needs to be created, e.g. "subnet-00000000,subnet-1111111"
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
security_groups:
description: |
Comma separated list of security group ids for the service when it needs to be created, e.g. "sg-00000000,sg-1111111"
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
public_ip:
description: |
Whether the task's elastic network interface receives a public IP address when the service needs to be created.
Only works with ECS deployment controller.
The default value is DISABLED.
default: DISABLED
type: enum
enum:
- ENABLED
- DISABLED
target_group:
description: |
The full ARN of the Elastic Load Balancing target group or groups associated with a service when it needs to be created.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
container_name:
description: |
The name of the container to associate with the load balancer when the service needs to be created.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
container_port:
description: |
The port on the container to associate with the load balancer when the service needs to be created.
This port must correspond to a containerPort in the task definition the tasks in the service are using.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string

steps:
- unless:
Expand All @@ -206,14 +266,14 @@ steps:
steps:
- run:
name: Retrieve previous task definition
command: >
command: |
TASK_DEFINITION_ARN=$(aws ecs describe-task-definition \
--task-definition << parameters.family >> \
--output text \
--query 'taskDefinition.taskDefinitionArn' \
--profile << parameters.profile_name >> \
--region << parameters.region >>)
echo "export CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN='${TASK_DEFINITION_ARN}'" >> $BASH_ENV
echo "export CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN=$TASK_DEFINITION_ARN" >> $BASH_ENV
- when:
condition: << parameters.task_definition_tags >>
steps:
Expand Down Expand Up @@ -267,6 +327,14 @@ steps:
ORB_AWS_REGION: << parameters.region >>
ORB_STR_PROFILE_NAME: <<parameters.profile_name>>
ORB_BOOL_ENABLE_CIRCUIT_BREAKER: <<parameters.enable_circuit_breaker>>
ORB_AWS_DESIRED_COUNT: <<parameters.desired_count>>
ORB_AWS_CREATE_SERVICE: <<parameters.create_service>>
ORB_STR_SUBNETS: <<parameters.subnets>>
ORB_STR_SECURITY_GROUPS: <<parameters.security_groups>>
ORB_PUBLIC_IP: <<parameters.public_ip>>
ORB_STR_TARGET_GROUP: <<parameters.target_group>>
ORB_STR_CONTAINER_NAME: <<parameters.container_name>>
ORB_CONTAINER_PORT: <<parameters.container_port>>

- when:
condition:
Expand Down
69 changes: 69 additions & 0 deletions src/jobs/deploy_service_update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,67 @@ parameters:
description: The executor to use for this job. By default, this will use the "default" executor provided by this orb.
type: executor
default: default
create_service:
type: boolean
description: |
Create the service if it does not exist already.
Only works with ECS deployment controller.
Default false.
default: false
desired_count:
description: |
The desired number of tasks to run. If empty it would keep the existing count.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
subnets:
description: |
Comma separated list of subnet ids for the service when it needs to be created, e.g. "subnet-00000000,subnet-1111111"
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
security_groups:
description: |
Comma separated list of security group ids for the service when it needs to be created, e.g. "sg-00000000,sg-1111111"
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
public_ip:
description: |
Whether the task's elastic network interface receives a public IP address when the service needs to be created.
Only works with ECS deployment controller.
The default value is DISABLED.
default: DISABLED
type: enum
enum:
- ENABLED
- DISABLED
target_group:
description: |
The full ARN of the Elastic Load Balancing target group or groups associated with a service when it needs to be created.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
container_name:
description: |
The name of the container to associate with the load balancer when the service needs to be created.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string
container_port:
description: |
The port on the container to associate with the load balancer when the service needs to be created.
This port must correspond to a containerPort in the task definition the tasks in the service are using.
Only works with ECS deployment controller.
Default to empty.
default: ""
type: string

executor: << parameters.executor >>
steps:
- steps: << parameters.auth >>
Expand Down Expand Up @@ -257,3 +318,11 @@ steps:
codedeploy_capacity_provider_weight: <<parameters.codedeploy_capacity_provider_weight>>
codedeploy_capacity_provider_base: <<parameters.codedeploy_capacity_provider_base>>
deployment_config_name: <<parameters.deployment_config_name>>
desired_count: <<parameters.desired_count>>
create_service: <<parameters.create_service>>
subnets: <<parameters.subnets>>
security_groups: <<parameters.security_groups>>
public_ip: <<parameters.public_ip>>
target_group: <<parameters.target_group>>
container_name: <<parameters.container_name>>
container_port: <<parameters.container_port>>
60 changes: 49 additions & 11 deletions src/scripts/update_service_via_task_def.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,64 @@ ORB_STR_CLUSTER_NAME="$(circleci env subst "$ORB_STR_CLUSTER_NAME")"
ORB_STR_SERVICE_NAME="$(circleci env subst "$ORB_STR_SERVICE_NAME")"
ORB_STR_PROFILE_NAME="$(circleci env subst "$ORB_STR_PROFILE_NAME")"
ORB_AWS_REGION="$(circleci env subst "$ORB_AWS_REGION")"
ORB_STR_SUBNETS="$(circleci env subst "$ORB_STR_SUBNETS")"
ORB_STR_SECURITY_GROUPS="$(circleci env subst "$ORB_STR_SECURITY_GROUPS")"
ORB_STR_TARGET_GROUP="$(circleci env subst "$ORB_STR_TARGET_GROUP")"

if [ -z "${ORB_STR_SERVICE_NAME}" ]; then
ORB_STR_SERVICE_NAME="$ORB_STR_FAMILY"
fi

if [ "$ORB_BOOL_FORCE_NEW_DEPLOY" == "1" ]; then
SERVICE_EXISTS=$(aws ecs describe-services \
--profile "${ORB_STR_PROFILE_NAME}" \
--cluster "$ORB_STR_CLUSTER_NAME" \
--services "${ORB_STR_SERVICE_NAME}" \
--query "services[?serviceName=='$ORB_STR_SERVICE_NAME'].serviceName" \
--region "${ORB_AWS_REGION}" \
--output text
)

if [ "$ORB_BOOL_FORCE_NEW_DEPLOY" == "1" ] && [ -n "$SERVICE_EXISTS" ]; then
set -- "$@" --force-new-deployment
fi

if [ "$ORB_BOOL_ENABLE_CIRCUIT_BREAKER" == "1" ]; then
set -- "$@" --deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true}"
fi

DEPLOYED_REVISION=$(aws ecs update-service \
--profile "${ORB_STR_PROFILE_NAME}" \
--cluster "$ORB_STR_CLUSTER_NAME" \
--service "${ORB_STR_SERVICE_NAME}" \
--task-definition "${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}" \
--output text \
--region "${ORB_AWS_REGION}" \
--query service.taskDefinition \
"$@")
echo "export CCI_ORB_AWS_ECS_DEPLOYED_REVISION='${DEPLOYED_REVISION}'" >> "$BASH_ENV"
if [ -n "$ORB_AWS_DESIRED_COUNT" ]; then
set -- "$@" --desired-count "$ORB_AWS_DESIRED_COUNT"
fi

if [ -n "$ORB_STR_SUBNETS" ] && [ -n "$ORB_STR_SECURITY_GROUPS" ] && [ -z "$SERVICE_EXISTS" ]; then
set -- "$@" --network-configuration "awsvpcConfiguration={subnets=[$ORB_STR_SUBNETS],securityGroups=[$ORB_STR_SECURITY_GROUPS],assignPublicIp=$ORB_PUBLIC_IP}"
fi

if [ -z "$SERVICE_EXISTS" ]; then
echo "The service doesn't exist."
if [ "$ORB_AWS_CREATE_SERVICE" = 1 ]; then
echo "Creating it."
set -x
NEW_SERVICE=$(aws ecs create-service \
--cluster "$ORB_STR_CLUSTER_NAME" \
--region "${ORB_AWS_REGION}" \
--profile "${ORB_STR_PROFILE_NAME}" \
--service-name "${ORB_STR_SERVICE_NAME}" \
--task-definition "${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}" \
--load-balancers "targetGroupArn=$ORB_STR_TARGET_GROUP,containerName=$ORB_STR_CONTAINER_NAME,containerPort=$ORB_CONTAINER_PORT" \
"$@")
set +x
echo "$NEW_SERVICE"
fi
else
DEPLOYED_REVISION=$(aws ecs update-service \
--profile "${ORB_STR_PROFILE_NAME}" \
--cluster "$ORB_STR_CLUSTER_NAME" \
--service "${ORB_STR_SERVICE_NAME}" \
--task-definition "${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}" \
--output text \
--region "${ORB_AWS_REGION}" \
--query service.taskDefinition \
"$@")
echo "export CCI_ORB_AWS_ECS_DEPLOYED_REVISION='${DEPLOYED_REVISION}'" >> "$BASH_ENV"
fi
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,9 @@ Resources:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PublicListener']]
Priority: !Ref 'Priority'

Outputs:
TargetGroupArn:
Value: !Ref TargetGroup
Export:
Name: TargetGroupArnExport
4 changes: 4 additions & 0 deletions tests/terraform_setup/ec2/terraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ resource "aws_cloudformation_stack" "ecs_service" {
# nginx image when created
}
}

output "target_group_arn" {
value = aws_cloudformation_stack.ecs_service.outputs["TargetGroupArn"]
}