In [ ]:
cat << EOT >> ~/config/.env
export STAGING_STACK_NAME="fargate-handson-staging-env"
EOT
Edge 環境のリソース定義に この パッチをあてます。
In [ ]:
patch ~/notebook/infrastructure/sam.yaml < ~/notebook/infrastructure/diff/staging
このテンプレートの適用により、以下のような構成へ更新していきます。
適用前に、新しい sam.yaml の内容が正しいことを検証します。
In [ ]:
aws cloudformation validate-template --template-body file://infrastructure/sam.yaml
成功時応答例)
{
"Description": "A fargate application with a CI/CD pipeline",
"Parameters": [
{
"ParameterKey": "ProjectID",
"NoEcho": false
},
..
Lambda 関数を含むテンプレートのため、パッケージングします。
In [ ]:
source ~/config/.env
aws cloudformation package \
--template-file infrastructure/sam.yaml \
--output-template-file infrastructure/cfn.yaml \
--s3-bucket "${S3_BUCKET_NAME}" \
--s3-prefix "cloudformation"
成功時応答)
Uploading to cloudformation/0e64849e597b443d9a1349275098ab43 766 / 766.0 (100.00%)
Successfully packaged artifacts and wrote output template to file infrastructure/cfn.yaml
..
パッケージングした CloudFormation テンプレートでインフラを更新します。
In [ ]:
aws cloudformation deploy \
--stack-name "${BASE_STACK_NAME}" \
--template-file infrastructure/cfn.yaml \
--parameter-overrides \
ProjectID="${PROJECT_ID}" \
S3BucketName="${S3_BUCKET_NAME}" \
EdgeStackName="${EDGE_STACK_NAME}" \
StagingStackName="${STAGING_STACK_NAME}" \
ApprovalEmail="${GIT_EMAIL_ADDRESS}" \
--capabilities CAPABILITY_IAM
成功時応答)
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - fargate-handson-base
こちら のテンプレートを使い、ステージング環境を作成します。
この環境はロードバランサーやオートスケーリングの設定がされ、本番環境を想定した構成になっています。
- CloudWatch Logs ロググループ
- ECS クラスター
- ECS タスク定義
- ECS サービス
- IAM ロール * 2
TODO: 図を用意する
開発環境 Fargate とステージング・本番環境 Fargate の差分を確認してみます。
In [ ]:
diff ~/notebook/application/deploy/cfn-master.yaml \
~/notebook/application/deploy/cfn-release.yaml
では実際にステージング環境の Fargate をデプロイしてみます。
In [ ]:
DOCKER_IMAGE=dockercloud/hello-world
aws cloudformation deploy \
--stack-name "${STAGING_STACK_NAME}" \
--template-file application/deploy/cfn-release.yaml \
--parameter-overrides \
ProjectID="${PROJECT_ID}" \
DockerImage="${DOCKER_IMAGE}" \
--capabilities CAPABILITY_IAM
成功時応答)
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - fargate-handson-staging-env
構築が完了したら、ステージング環境の Fargate を確認してみましょう。
In [ ]:
STAGING_ENDPOINT="http://$( aws cloudformation describe-stacks \
--stack-name "${STAGING_STACK_NAME}" --output text \
--query 'Stacks[*].Outputs[?OutputKey==`LoadBalancerDNSName`].OutputValue' )"
cat << EOT >> ~/config/.env
export STAGING_ENDPOINT="${STAGING_ENDPOINT}"
EOT
echo "${STAGING_ENDPOINT}"
応答例)
http://farga-LoadB-xxx-xxx.ap-northeast-1.elb.amazonaws.com
ロードバランサー経由で Fargate にアクセスできましたか?
オートスケーリングの設定もされており、これで負荷分散する Fargate の完成です。
In [ ]:
cd ~/notebook/application
git log -1
aws codecommit create-branch \
--repository-name "fargate-handson" \
--branch-name "release" \
--commit-id "$( git log -1 --pretty=%H )"
応答例)
commit 2236df05287049512148f204395f0d433c47a382 (HEAD -> master, origin/master)
Author: foo <foo@bar.com>
Date: Mon Jul 23 13:24:04 2018 +0000
first commit
CodePipeline のコンソールから、リリース版パイプライン が更新されるのを眺めます。
In [ ]:
codebuild_project_name=$( aws cloudformation describe-stacks \
--stack-name "${BASE_STACK_NAME}" --output text \
--query 'Stacks[*].Outputs[?OutputKey==`CodePipelineRelease`].OutputValue' )
codebuild_console="https://ap-northeast-1.console.aws.amazon.com/codepipeline/home"
echo "${codebuild_console}?region=${AWS_DEFAULT_REGION}#/view/${codebuild_project_name}"
更新されたら、Fargate の内容が新しくなっていることを確認しましょう。
In [ ]:
echo "${STAGING_ENDPOINT}"
In [ ]:
cd ~/notebook/application
cat << EOF > Dockerfile
FROM pottava/proxy
ENV APP_PORT=80 \\
PROXY_PATTERNS="*=http://ip-api.com/json" \\
HEALTHCHECK_PATH=/health \\
ACCESS_LOG=true
EOF
cat << EOT > deploy/edge/env.sh
export BASIC_AUTH="BasicAuthUsername":"edge","BasicAuthPassword":"fargate"
EOT
chmod +x deploy/edge/env.sh
cat << EOT > deploy/staging/env.sh
export BASIC_AUTH="BasicAuthUsername":"staging","BasicAuthPassword":"fargate"
EOT
chmod +x deploy/staging/env.sh
git add .
git commit -m "reverse-proxy to ip-api.com"
git push
応答例)
[master 628191e] reverse-proxy to ip-api.com
2 files changed, 2 insertions(+), 2 deletions(-)
Counting objects: 7, done.
..
開発(Edge)環境のパイプラインが動き、環境が更新されます。
内容が正しそうか確認しましょう。
In [ ]:
codebuild_project_name=$( aws cloudformation describe-stacks \
--stack-name "${BASE_STACK_NAME}" --output text \
--query 'Stacks[*].Outputs[?OutputKey==`CodePipeline`].OutputValue' )
codebuild_console="https://ap-northeast-1.console.aws.amazon.com/codepipeline/home"
echo "${codebuild_console}?region=${AWS_DEFAULT_REGION}#/view/${codebuild_project_name}"
In [ ]:
cluster_name=$( aws cloudformation describe-stacks \
--stack-name "${EDGE_STACK_NAME}" --output text \
--query 'Stacks[*].Outputs[?OutputKey==`Cluster`].OutputValue' )
task_id=$( aws ecs list-tasks --cluster "${cluster_name}" \
--family "${EDGE_STACK_NAME}" | jq -r '.taskArns[0]' )
eni_id=$( aws ecs describe-tasks --cluster "${cluster_name}" --task "${task_id}" \
| jq '.tasks[0].attachments[0].details[]' \
| jq -r 'select( .name | contains("networkInterfaceId")).value' )
edge_endpoint="http://$( aws ec2 describe-network-interfaces \
--network-interface-ids ${eni_id} \
| jq -r '.NetworkInterfaces[].Association.PublicIp' )"
echo "${edge_endpoint}/json"
Basic 認証は上記変更の通り、ユーザー名は edge、パスワードは fargate です。
ブラウザでアクセスすると、以下のような JSON か返ってくるかと思います。
応答例)
{
as: "AS16509 Amazon.com, Inc.",
countryCode: "JP",
city: "Tokyo",
country: "Japan",
isp: "Amazon.com",
query: "13.115.178.180",
..
}
Edge 環境で動作確認が取れたら、release ブランチに対してプルリクエストを作成します。
In [ ]:
repo="fargate-handson"
aws codecommit create-pull-request \
--title "My first Pull Request" \
--description "Please review this immediately!" \
--targets "repositoryName=${repo},sourceReference=master,destinationReference=release"
応答例)
{
"pullRequest": {
"pullRequestId": "1",
"title": "My first Pull Request",
"description": "Please review this immediately!",
"pullRequestTargets": [
{
"repositoryName": "fargate-handson",
"sourceReference": "refs/heads/master",
"destinationReference": "refs/heads/release",
..
}
残念ながら、孤独に一人で開発中なので、自分でレビューをしてマージしましょう・・
https://ap-northeast-1.console.aws.amazon.com/codecommit/home?region=ap-northeast-1#/repository/fargate-handson/pull-requests
release ブランチにマージされると、ステージング環境へのデプロイが開始されます。
In [ ]:
codebuild_project_name=$( aws cloudformation describe-stacks \
--stack-name "${BASE_STACK_NAME}" --output text \
--query 'Stacks[*].Outputs[?OutputKey==`CodePipelineRelease`].OutputValue' )
codebuild_console="https://ap-northeast-1.console.aws.amazon.com/codepipeline/home"
echo "${codebuild_console}?region=${AWS_DEFAULT_REGION}#/view/${codebuild_project_name}"
ステージング環境でも内容が変更されたことを確認してみましょう。
In [ ]:
echo "${STAGING_ENDPOINT}/json"
Basic 認証のユーザー名は staging、パスワードは fargate です。
開発環境同様、以下のような JSON か返ってくれば OK です!
応答例)
{
as: "AS16509 Amazon.com, Inc.",
countryCode: "JP",
city: "Tokyo",
country: "Japan",
isp: "Amazon.com",
query: "13.115.178.180",
..
}