GitLabとECSを組み合わせてCI/CDをしたい場合、以下が.gitlab-ci.yml
で実装できれば実現できそうである。
- コンテナイメージのビルド&格納
- 格納したイメージでECS上にコンテナを起動する
これを動作確認した時のメモ。
なお、前準備として以下を実施している。
- タスク定義を作るためにベースとなるコンテナを作成
- ECSにベースとなるタスク定義を登録し、サービスを起動
今回のパイプラインは上記の前準備で作ったものを更新していく。
前準備については長くなったので、付録に回している。
CI/CDからイメージを更新する
ここの内容は以下のブログを参考にした。
流れとしては以下となる。
- タスク定義を作成する
- タスク定義内のイメージ名を更新する
- タスク定義を更新する
- サービスを上げ直す
一度、上記の手順をローカルで確認する。
最初に、必要な環境変数を定義する。
# タスク定義内のfamily
export ECS_FAMILY=ecs-test-project
# ECSクラスタ名
export ECS_CLUSTER=imurata-ecs-cluster
# ECSクラスタ内のサービス名
export ECS_SERVICE=ecs-test-project
# kpack/TBSでのイメージ名
export K8S_IMAGE=hello-tanzu-ecs
# kpack/TBSでのイメージのNamespace
export K8S_NAMESPACE=cicd
タスク定義を取り出す。
aws ecs describe-task-definition --task-definition ${ECS_FAMILY} | jq '.taskDefinition | del (.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' > ./taskdef.json
イメージのハッシュ値を取得し、タスク定義に上書きする。
IMAGE=$(kubectl get image $K8S_IMAGE -n $K8S_NAMESPACE -o jsonpath={.status.latestImage})
sed -i "s|\"image\": .*,|\"image\": \"$IMAGE\",|g" taskdef.json
更新したタスク定義を登録する。
aws ecs register-task-definition --cli-input-json file://taskdef.json
ECSのサービスを更新する。
aws ecs update-service --cluster $ECS_CLUSTER --service ${ECS_SERVICE} --task-definition ${ECS_FAMILY}
ここまで実施し、タスク定義のリビジョンが更新されることと、新しいリビジョンでサービスが起動することを確認した。
次に、上記で確認した手順を.gitlab-ci.yml
に書いていく。
awsコマンドをパイプラインから叩くにあたり、アクセスキー、シークレットアクセスキー、リージョンを環境変数として定義する必要があるが、.gitlab-ci.yml
に記載すると事故の元なので、GitLab内に登録しておく。GitLabのUIから登録するか、以下のようにAPIでまとめて登録する。
export GITLAB_URL=https://gitlab.gitlab.hogeeee.info
export GITLAB_PROJECT_ID=45
export GITLAB_TOKEN="xxxxxxxx"
export AWS_ACCESS_KEY_ID=xxxxx
export AWS_SECRET_ACCESS_KEY=xxxxx
export AWS_DEFAULT_REGION=us-east-1
curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"${GITLAB_URL}/api/v4/projects/${GITLAB_PROJECT_ID}/variables" --form "key=AWS_ACCESS_KEY_ID" --form "value=$AWS_ACCESS_KEY_ID" --form "protected=true" --form "masked=true"
curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"${GITLAB_URL}/api/v4/projects/${GITLAB_PROJECT_ID}/variables" --form "key=AWS_SECRET_ACCESS_KEY" --form "value=$AWS_SECRET_ACCESS_KEY" --form "protected=true" --form "masked=true"
curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"${GITLAB_URL}/api/v4/projects/${GITLAB_PROJECT_ID}/variables" --form "key=AWS_DEFAULT_REGION" --form "value=$AWS_DEFAULT_REGION"
先程ローカルで試した手順を.gitlab-ci.yml
に書き出す。最終的に.gitlab-ci.yml
は以下のようになった。
stages:
- build
- deploy
build-image:
image: docker:dind
stage: build
variables:
BUILD_NAMESPACE: "cicd"
HARBOR_USERNAME: "xxxx"
HARBOR_PASSWORD: "xxxx"
HARBOR_URL: "core.harbor.hogeeee.info"
K8S_IMAGE: hello-tanzu-ecs
before_script:
- wget -q https://github.com/vmware-tanzu/kpack-cli/releases/download/v0.10.0/kp-linux-amd64-0.10.0 -O /usr/local/bin/kp && chmod +x /usr/local/bin/kp
script:
|-
set -x
docker login -u $HARBOR_USERNAME -p $HARBOR_PASSWORD $HARBOR_URL
kp image save $K8S_IMAGE --tag ${CI_REGISTRY_IMAGE} \
--namespace ${BUILD_NAMESPACE} \
--local-path ./ \
--wait
deploy-image-to-ecs:
image: python
stage: deploy
variables:
KUBE_VERSION: 1.24.0
ECS_FAMILY: ecs-test-project
ECS_CLUSTER: imurata-ecs-cluster
ECS_SERVICE: ecs-test-project
K8S_IMAGE: hello-tanzu-ecs
K8S_NAMESPACE: cicd
before_script:
- pip install awscli
- wget -q https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl
- wget -q https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O /usr/local/bin/jq && chmod +x /usr/local/bin/jq
script:
|-
set -x
aws ecs describe-task-definition --task-definition ${ECS_FAMILY} | jq '.taskDefinition | del (.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' > ./taskdef.json
IMAGE=$(kubectl get image $K8S_IMAGE -n $K8S_NAMESPACE -o jsonpath={.status.latestImage})
sed -i "s|\"image\": .*,|\"image\": \"$IMAGE\",|g" taskdef.json
aws ecs register-task-definition --cli-input-json file://taskdef.json
aws ecs update-service --cluster $ECS_CLUSTER --service ${ECS_SERVICE} --task-definition ${ECS_FAMILY}
これをコミットした状態で、ソースコードを変更する。
src/main/java/org/example/tanzu/HelloServlet.java
を編集し、Hello Tanzu!
をHello Tanzu! edited
に変更した。
void printHello(PrintWriter pw) {
pw.print("<h3>");
pw.print("Hello Tanzu! edited");
pw.print("</h3>");
pw.print("<p>");
これをコミットすると、パイプラインが実行され、最初にイメージが更新され、ECS上でそのイメージで起動する。
なお、パイプラインの実行完了後、サービスが起動するまで数分程度待つため、直ぐにアクセスしても変化がない点は注意となる。
付録:前準備
サンプルイメージの作成
最初にサンプルコードをGitLabに登録する。Hello TanzuというサンプルをGitLabにImportする。
次に、.gitlab-ci.yml
を作成する。
CI/CD
->Editor
をクリックし、Configure pipeline
をクリックする。
デフォルトの記述を削除し、コンテナイメージをビルドするよう記載する。ここではコンテナのビルドとpushにkpack(Tanzu Build Service)を使うことを想定している。
build-image:
image: docker:dind
stage: build
variables:
BUILD_NAMESPACE: "cicd"
HARBOR_USERNAME: "xxxx"
HARBOR_PASSWORD: "xxxx"
HARBOR_URL: "core.harbor.hogeeee.info"
HARBOR_REPO: "myapp"
K8S_IMAGE: hello-tanzu-ecs
before_script:
- wget -q https://github.com/vmware-tanzu/kpack-cli/releases/download/v0.10.0/kp-linux-amd64-0.10.0 -O /usr/local/bin/kp && chmod +x /usr/local/bin/kp
script:
|-
set -x
docker login -u $HARBOR_USERNAME -p $HARBOR_PASSWORD $HARBOR_URL
kp image save $K8S_IMAGE --tag ${HARBOR_URL}/${HARBOR_REPO}/${K8S_IMAGE} \
--namespace ${BUILD_NAMESPACE} \
--local-path ./ \
--wait
kpコマンドが叩けるkpack/kp
というイメージがdockerhubに公開されているが、ローカルのファイルを使ってビルドする場合はdocker loginしておく必要がある(kpackがイメージレジストリにソースをuploadするため)ので、kpack/kp
は使わずdocker:dind
にkpコマンドを取り込むようにし、kpコマンド実行前にdocker loginしている。
なお、イメージの格納先がGitLabの人は環境変数を定義せず、CI_REGISTRY_IMAGE
などのCI上で使える環境変数を使ってログイン、pushするとよい。
kpackを使わずdocker build/pushを行う場合はこの辺りが参考になると思う。
上記ジョブをコミットして実行後、k8sクラスタからハッシュ値付きイメージ名を取得する。
$ kp image status hello-tanzu-ecs | grep Latest
LatestImage: core.harbor.hogeeee.info/myapp/hello-tanzu-ecs@sha256:1b2799402dd34385f940412e1a624e0b42dc29c6289dd6a84c96b2ccb534c6f6
ECS CLIの導入
こちらの手順に従ってインストールする。
sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest
brew install gnupg
cat << 'EOF' > /tmp/pubkey.txt
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
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
=Gi5D
-----END PGP PUBLIC KEY BLOCK-----
EOF
gpg --import /tmp/pubkey.txt
curl -Lo ecs-cli.asc https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest.asc
gpg --verify ecs-cli.asc /usr/local/bin/ecs-cli
sudo chmod +x /usr/local/bin/ecs-cli
ECSのタスク実行ロールの作成
この辺を参考にしつつロールを作成する。
export TASK_ROLE_NAME=ecsTaskExecutionRole
cat << EOF > ./task-execution-assume-role.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name $TASK_ROLE_NAME --assume-role-policy-document file://task-execution-assume-role.json
aws iam attach-role-policy \
--role-name $TASK_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
また、コンテナのイメージレジストリの認証情報をSecretManagerに登録している。これにアクセス出来るようにするために、ロールを追加する。
export POLICY_NAME=ecsGetSecretPolicy
cat << EOF > ./secret-assume-role.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:secretsmanager:us-east-1:xxxxxxx:secret:harbor-secret-550KBB"
]
}
]
}
EOF
aws iam put-role-policy \
--role-name $TASK_ROLE_NAME \
--policy-name $POLICY_NAME \
--policy-document file://secret-assume-role.json
ECSの初期設定
こちらをかなり参考にさせていただいた。
ECSクラスタの設定を登録する。
export ECS_CLUSTER=imurata-ecs-cluster
export ECS_CLUSTER_CONFIG=imurata-ecs-config
export ECS_LAUNCH_TYPE="FARGATE"
export AWS_REGION=us-east-1
ecs-cli configure --region $AWS_REGION --cluster $ECS_CLUSTER --default-launch-type $ECS_LAUNCH_TYPE --config-name $ECS_CLUSTER_CONFIG
ECS CLI用のプロファイルを作成する
export ECS_PROFILE=imurata-ecs-profile
ecs-cli configure profile --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY --profile-name $ECS_PROFILE
ECSのクラスタを起動する。
ecs-cli up --cluster-config $ECS_CLUSTER_CONFIG --ecs-profile $ECS_PROFILE
出力結果は以下。
INFO[0002] Created cluster cluster=imurata-ecs-cluster region=us-east-1
INFO[0003] Waiting for your cluster resources to be created...
INFO[0004] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
VPC created: vpc-00a6c03bd7210e5ca
Subnet created: subnet-07829826247054ae0
Subnet created: subnet-0274c60f646e087db
Cluster creation succeeded.
VPCとSubnetを変数化する。
export ECS_VPC=vpc-04109114dae7d0876
export ECS_SUBNET1=subnet-0688829722c4ed724
export ECS_SUBNET2=subnet-0211bfc69638fa8b4
VPCのセキュリティグループのIDを取得する。
aws ec2 describe-security-groups --filters Name=vpc-id,Values=$ECS_VPC | grep -i groupid
環境変数に設定する。
export ECS_SG=sg-083869eb63363ced2
セキュリティグループのインバウンドルールにPort80に対して自IPを通すよう設定する。
aws ec2 authorize-security-group-ingress --group-id $ECS_SG --ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges=[{CidrIp=$(curl https://checkip.amazonaws.com 2> /dev/null | tr -d '\r\n')/32}]
次にALBを作成する。
export ECS_LB=ecs-test-lb
aws elbv2 create-load-balancer --name $ECS_LB --subnets $ECS_SUBNET1 $ECS_SUBNET2 --security-groups $ECS_SG
LoadBalancerArnの値を変数化する。
export ECS_LB_ARN="arn:aws:elasticloadbalancing:us-east-1:xxxxx:loadbalancer/app/ecs-test-lb/b2dfddc492d8fed0"
ターゲットグループを作成する。
export ECS_TARGET=ecs-test-target
aws elbv2 create-target-group --name $ECS_TARGET --protocol HTTP --port 8080 --target-type ip --vpc-id $ECS_VPC
ターゲットグループのArnを変数化する。
export ECS_TARGET_ARN="arn:aws:elasticloadbalancing:us-east-1:xxxxx:targetgroup/ecs-test-target/9865f22ac7242fd7"
ALBのリスナーを作成する。
aws elbv2 create-listener --load-balancer-arn $ECS_LB_ARN --protocol HTTP --port 8080 --default-actions Type=forward,TargetGroupArn=$ECS_TARGET_ARN
ecs-cliを利用してタスク定義を生成してサービスを立ち上げるためにdocker-compose.ymlとecs-params.ymlを作成する。image:
には事前に作成したコンテナイメージを指定する。
cat << EOF > ./docker-compose.yml
version: '3'
services:
web:
image: core.harbor.hogeeee.info/myapp/hello-tanzu-ecs@sha256:1b2799402dd34385f940412e1a624e0b42dc29c6289dd6a84c96b2ccb534c6f6
ports:
- '80:80'
- '8080:8080'
logging:
driver: awslogs
options:
awslogs-group: /etc/imurata-Logs
awslogs-region: us-east-1
awslogs-stream-prefix: ecs
EOF
cat << EOF > ./ecs-params.yml
version: 1
task_definition:
task_execution_role: ecsTaskExecutionRole
ecs_network_mode: awsvpc
services:
web:
repository_credentials:
credentials_parameter: arn:aws:secretsmanager:us-east-1:xxxxx:secret:harbor-secret-550KBB
task_size:
mem_limit: 1GB
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- $ECS_SUBNET1
- $ECS_SUBNET2
security_groups:
- $ECS_SG
assign_public_ip: ENABLED
EOF
docker-compose.ymlとecs-params.ymlがあるディレクトリでecs-cli compose
でコンテナを起動する。
export ECS_PROJECT=ecs-test-project
ecs-cli compose --project-name $ECS_PROJECT service up --create-log-groups --cluster-config $ECS_CLUSTER_CONFIG --ecs-profile $ECS_PROFILE --target-group-arn $ECS_TARGET_ARN --container-name web --container-port 8080
出力結果は以下。
INFO[0002] Using ECS task definition TaskDefinition="ecs-test-project:1"
WARN[0003] Failed to create log group /etc/imurata-Logs in us-east-1: The specified log group already exists
INFO[0003] Auto-enabling ECS Managed Tags
INFO[0010] (service ecs-test-project) has started 1 tasks: (task 1c94b09279e24abdb828bc9632db78b9). timestamp="2023-03-26 06:11:04 +0000 UTC"
INFO[0037] (service ecs-test-project) registered 1 targets in (target-group arn:aws:elasticloadbalancing:us-east-1:xxxxx:targetgroup/ecs-test-target/7c71684bd9c1d55f) timestamp="2023-03-26 06:11:31 +0000 UTC"
INFO[0042] Service status desiredCount=1 runningCount=1 serviceName=ecs-test-project
INFO[0042] ECS Service has reached a stable state desiredCount=1 runningCount=1 serviceName=ecs-test-project
INFO[0042] Created an ECS service service=ecs-test-project taskDefinition="ecs-test-project:1"
接続先を確認する。
aws elbv2 describe-load-balancers --load-balancer-arns $ECS_LB_ARN | grep DNSName