各種バージョン情報
$ terraform -v
Terraform v0.14.6
# FARGATEプラットフォームのバージョン 1.4.0
チェックポイント
自分が特に気にしたポイントを列挙します。
- ECRのイメージを利用する場合は、ECSから以下2つのECRエンドポイントへアクセスができること
- 詳細はAmazon ECR VPC エンドポイントに関する考慮事項より
- com.amazonaws.ap-northeast-1.ecr.api
- com.amazonaws.ap-northeast-1.ecr.dkr
- awslogdriverを利用する場合は、ECSからlogsエンドポイントへアクセスができること
- com.amazonaws.ap-northeast-1.logs
- ECSタスク実行IAMロールがSecretManagerが参照でき、その暗号化に利用したKMSの利用ができること
- ECSタスクのcpuとmemoryが正しい組み合わせかどうか
- cpu→256、memory→256などは✗
- 組み合わせ可能リストはこちら
- ECSタスク起動時にLatest指定すると1.3.0で起動してしまうので注意
- 20210307確認
- Fargate 1.3.0で、SecretManagerを利用するには1工夫が必要で同じ使い方ができない
- 具体的には1つの環境変数にすべての値が挿入されてしまうのでコンテナ起動後にシェルスクリプトなどで分解する必要がある
- 1.4.0からは特定の値を1つの環境変数に挿入できるようになった
とりまTerraformで書いてみましょ
ファイル数多いので全体はGitHubに置きました
重要なポイントだけ以下に書きます。
コンテナにSecretManagerの値を渡す部分
- ECSタスクの定義
sample_ecs_fargate/_modules/app/ecstaskdefinition.tf
resource "aws_ecs_task_definition" "debug" {
container_definitions = templatefile("${path.module}/template/debug.json", {
env = var.env
version = var.image_version
image = var.image_name
debug_log = aws_cloudwatch_log_group.debug.name
app_name = var.project
secret_arn = aws_secretsmanager_secret.my_sandbox.arn
})
〜略〜
sample_ecs_fargate/_modules/app/template/debug.json
[
〜〜略〜〜
"networkMode": "awsvpc",
"environment": [
{
"name": "ENV",
"value": "${env}"
},
{
"name": "APP_NAME",
"value": "${app_name}"
}
],
"secrets": [
{
"name": "HOGE",
"valueFrom": "${secret_arn}:HOGE::"
# ↑こんなかんじにARN+キー名で指定してあげるとできる
}
]
〜〜略〜〜
- SecretManagerの定義
sample_ecs_fargate/_modules/app/secretmanager.tf
resource "aws_secretsmanager_secret" "my_sandbox" {
name = "tmp/sandbox/secret"
description = "my_sandbox secret"
recovery_window_in_days = 0
}
resource "aws_secretsmanager_secret_version" "my_sandbox" {
secret_id = aws_secretsmanager_secret.my_sandbox.id
secret_string = templatefile("${path.module}/template/secretmanager.json", {
env = var.env
})
}
sample_ecs_fargate/_modules/app/template/secretmanager.json
{
"ENV": "${env}",
"HOGE": "SECRET!!"
}
コンテナイメージのLatest運用をやめる
- CircleCI側のJobでDockerイメージの作成、ECRへの登録、ECSサービスとECSタスクの更新を行っている
- ※terraform apply直後はLatest運用になってしまう問題は残っているがCircleCIからイメージとECSサービスのアップデートをすれば更新される
.circleci/config.yml
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@6.15.2
aws-ecs: circleci/aws-ecs@1.4.0
workflows:
build_and_push_image_dev:
jobs:
# approval使っているのは完全にぼくの好み
# 自動デプロイはまだ正直コワイ
- approval-to-build-and-deploy:
type: approval
- aws-ecr/build-and-push-image:
requires:
- approval-to-build-and-deploy
name: build-and-push-debug-image
account-url: AWS_ECR_HOST # 12341234.dkr.ecr.ap-northeast-1.amazonaws.com
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
create-repo: true
dockerfile: "docker/debug/Dockerfile"
no-output-timeout: 20m
repo: "my-sandbox/debug"
skip-when-tags-exist: false
tag: "latest,${CIRCLE_SHA1}"
- aws-ecs/deploy-service-update:
name: deploy-service-update
requires:
- build-and-push-debug-image
aws-region: "ap-northeast-1"
aws-access-key-id: "${AWS_ACCESS_KEY_ID}"
aws-secret-access-key: "${AWS_SECRET_ACCESS_KEY}"
family: "my-sundbox-debug-family"
service-name: "my-sundbox-debug"
cluster-name: "arn:aws:ecs:ap-northeast-1:12341234:cluster/my-sundbox-cluster"
container-image-name-updates: "container=debug,tag=${CIRCLE_SHA1}"
# ↑ここでtagを指定してECSサービスとECSタスクをアップデートしているのが肝
# 渡すべきパラメーターがStringだったりenv_var_nameだったりして少し使いにくかったのでそこらへんよしなにやってほしい。。。
AWS CLIからECSタスクの起動方法
今回はWebページを作ってないので、コマンドでECSタスクを起動してみましょう
# subnet-aaaaaaaはECSタスクを配置したいサブネットID
# sg-bbbbbbbはECSタスクにアタッチするセキュリティグループID
# --platform-versionは指定しないとデフォルトの1.3.0になるので注意
aws ecs run-task \
--cluster "my-sundbox-cluster" \
--task-definition "my-sundbox-debug-family" \
--launch-type "FARGATE" \
--platform-version "1.4.0" \
--network-configuration "awsvpcConfiguration={subnets=['subnet-aaaaaaa'],securityGroups=['sg-bbbbbbb'],assignPublicIp='DISABLED'}" \
--profile ${AWSプロファイル名}
{
"tasks": [
{
"attachments": [
〜後略〜
# コマンドが成功すると起動したタスク情報が表示されます
ちゃんとSecretManagerの値が環境変数に入りました。