前の記事 では、手動でデプロイしていましたが、 人間様がわざわざ AWSコンソールをポチポチやるなんて非効率ですし、いつかミスをするに決まっています。
そこで今回は Terraform を使って自動化してみることにします。
準備
必要なソフトウェアのインストールをします。
不要な場合は読み飛ばしてください。
tfenv
Terraform は活発に更新されているので バージョンアップによって仕様が変わり、不具合が発生しないとも言い切れません。
もちろん Terraform 単体でも動きますが、 tfenv
を使うと案件ごとに Terraform
のバージョンを使い分けられたりして便利なので積極的に使っていきたいです。
というわけでインストールします。
$ git clone https://github.com/tfutils/tfenv ~/.tfenv
Cloning into '/home/righ/.tfenv'...
remote: Enumerating objects: 725, done.
remote: Total 725 (delta 0), reused 0 (delta 0), pack-reused 725
Receiving objects: 100% (725/725), 105.98 KiB | 384.00 KiB/s, done.
Resolving deltas: 100% (453/453), done.
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
$ tfenv install latest
[INFO] Installing Terraform v0.12.0
[INFO] Downloading release tarball from https://releases.hashicorp.com/terraform/0.12.0/terraform_0.12.0_linux_amd64.zip
##O=-# #
curl: (22) The requested URL returned error: 403
tfenv: tfenv-install: [ERROR] Tarball download failed
おや ..
0.12.0 をインストールしようとしたけどないだと
$ tfenv list
* 0.11.11 (set by /home/righ/.tfenv/version)
$ tfenv list-remote
0.12.0
0.11.11
0.11.9
0.11.9-beta1
ブラウザで見に行くと
うーん、この
現時点では 0.12.0 は出てないようなので、 0.11.11 をインストールします
tfenv install 0.11.11
[INFO] Installing Terraform v0.11.11
[INFO] Downloading release tarball from https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip
######################################################################################################################## 100.0%
[INFO] Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_SHA256SUMS
tfenv: tfenv-install: [WARN] No keybase install found, skipping GPG signature verification
Archive: tfenv_download.KCaXZs/terraform_0.11.11_linux_amd64.zip
inflating: /home/righ/.tfenv/versions/0.11.11/terraform
[INFO] Installation of terraform v0.11.11 successful
[INFO] Switching to v0.11.11
[INFO] Switching completed
OK ぽいです。
今回はとりあえず以下ののバージョンを使います
$ terraform --version
Terraform v0.11.11
参考
https://qiita.com/kamatama_41/items/ba59a070d8389aab7694 https://blue1st-tech.hateblo.jp/entry/2017/09/16/230132
Terraform について
Terraform についてよく知らなかったのですこし勉強しました。 すで詳しい人は次のセクションまで飛ばしてください。
重要なポイントを自分なりに整理すると以下のような感じでしょうか。
- 変数は variable で宣言できる
- 環境変数や、実行時引数、 module の引数から値を渡すことができる
- 指定しない場合 default が使われる
- Terraform の実行単位はディレクトリ
<リソースの種類>.<リソース名>.<属性名>
のようにして、リソースの属性値を参照できる- 作成されたリソースの属性も同様に参照できる
- リソースの作成順は depends_on で制御できる
読み込みがディレクトリ単位というのは 少し特殊な概念なのでちゃんと理解しましょう。(Golangのパッケージっぽい)
参考
https://dev.classmethod.jp/cloud/terraform-getting-started-with-aws/ https://github.com/hashicorp/best-practices/tree/master/terraform/providers/aws https://dev.classmethod.jp/devops/directory-layout-bestpractice-in-terraform/ https://qiita.com/minamijoyo/items/1f57c62bed781ab8f4d7
ECSにアプリをデプロイする
Django を ECS(Fargate) に手動デプロイしたログ のシナリオと同様にサンプル用アプリケーションを ECS にデプロイします。
さて、単に Terraform を使ってデプロイすると言っても、 すべてのリソースを毎回作成する必要があるとは限りません。
例えば、ECR のコンテナリポジトリは一度作成すればよく、 すでにある状態で作成しようとするとエラーになります。
そこで「初回のみ作成するリソース」と「毎回作成するリソース」に
わけ、前者は init
というディレクトリの中に作成します。
このように、用途別にディレクトリを区切るのが Terraform のやり方のようです。
今回は次のような構成にしました。 わかりやすさ重視なので、ベストプラクティスには従っていません。
- setup/
-
- init/
-
ecr.tf
variable "app-repo" { default = "djample-app" } variable "nginx-repo" { default = "djample-nginx" } resource "aws_ecr_repository" "app-repo" { name = "${var.app-repo}" } resource "aws_ecr_repository" "nginx-repo" { name = "${var.nginx-repo}" } output "app-repo-url" { value = "${aws_ecr_repository.app-repo.repository_url}" } output "nginx-repo-url" { value = "${aws_ecr_repository.nginx-repo.repository_url}" }
-
provider.tf
variable access_key {} variable secret_key {} variable region { default = "us-west-2" } provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "${var.region}" }
-
-
provider.tf
variable access_key {} variable secret_key {} variable region { default = "us-west-2" } provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "${var.region}" }
-
iam.tf
resource "aws_iam_role" "default" { name = "assume_role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF } resource "aws_iam_role_policy" "default" { name = "assume_role_policy" role = "${aws_iam_role.default.id}" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": "*" } ] } EOF }
-
variables.tf
variable db_instance_name { default = "djample" } variable db_name { default = "djampledb" } variable db_user { default = "djampleuser" } variable db_password { default = "djamplepass" }
-
vpc.tf
variable availability_zone1 { default = "us-west-2a" } variable availability_zone2 { default = "us-west-2b" } variable availability_zone3 { default = "us-west-2c" } resource "aws_vpc" "default" { cidr_block = "10.0.0.0/16" } resource "aws_subnet" "default1" { vpc_id = "${aws_vpc.default.id}" cidr_block = "10.0.1.0/24" availability_zone = "${var.availability_zone1}" } resource "aws_subnet" "default2" { vpc_id = "${aws_vpc.default.id}" cidr_block = "10.0.2.0/24" availability_zone = "${var.availability_zone2}" } resource "aws_subnet" "default3" { vpc_id = "${aws_vpc.default.id}" cidr_block = "10.0.3.0/24" availability_zone = "${var.availability_zone3}" } resource "aws_db_subnet_group" "default" { name = "test-db-subnet" description = "test db subnet" subnet_ids = [ "${aws_subnet.default1.id}", "${aws_subnet.default2.id}", "${aws_subnet.default3.id}", ] } resource "aws_internet_gateway" "default" { vpc_id = "${aws_vpc.default.id}" tags = { Name = "djample-igw" } } resource "aws_route_table" "default" { vpc_id = "${aws_vpc.default.id}" route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.default.id}" } tags = { Name = "main" } } resource "aws_route_table_association" "a1" { subnet_id = "${aws_subnet.default1.id}" route_table_id = "${aws_route_table.default.id}" } resource "aws_route_table_association" "a2" { subnet_id = "${aws_subnet.default2.id}" route_table_id = "${aws_route_table.default.id}" } resource "aws_route_table_association" "a3" { subnet_id = "${aws_subnet.default3.id}" route_table_id = "${aws_route_table.default.id}" }
-
security_group.tf
resource "aws_security_group" "web" { name = "djample-web-sg" description = "Allow traffic for web" vpc_id = "${aws_vpc.default.id}" ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_security_group" "db" { name = "djample-db-sg" description = "Allow traffic for db" vpc_id = "${aws_vpc.default.id}" ingress { from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = ["${aws_security_group.web.id}"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }
-
rds.tf
resource "aws_db_parameter_group" "default" { name = "djample-parameter-group" family = "postgres10" description = "djample postgresql parameter" parameter { name = "log_min_duration_statement" value = "100" } } resource "aws_db_instance" "default" { allocated_storage = 10 storage_type = "gp2" engine = "postgres" engine_version = "10.4" instance_class = "db.t2.micro" identifier = "${var.db_instance_name}" name = "${var.db_name}" username = "${var.db_user}" password = "${var.db_password}" db_subnet_group_name = "${aws_db_subnet_group.default.name}" vpc_security_group_ids = ["${aws_security_group.db.id}"] parameter_group_name = "${aws_db_parameter_group.default.id}" depends_on = ["aws_security_group.db"] skip_final_snapshot = true }
-
alb.tf
variable "domain" { default = "*.crohaco.net" } variable "security-policy" { default = "ELBSecurityPolicy-2016-08" } resource "aws_alb" "default" { name = "djample-alb" internal = false security_groups = [ "${aws_security_group.web.id}", ] subnets = [ "${aws_subnet.default1.id}", "${aws_subnet.default2.id}", "${aws_subnet.default3.id}", ] } resource "aws_alb_target_group" "default" { name = "djample-target-group" protocol = "HTTP" port = "80" vpc_id = "${aws_vpc.default.id}" target_type = "ip" health_check { path = "/" } } resource "aws_alb_listener" "http" { load_balancer_arn = "${aws_alb.default.arn}" port = "80" protocol = "HTTP" default_action { target_group_arn = "${aws_alb_target_group.default.arn}" type = "forward" } depends_on = [ "aws_alb_target_group.default", "aws_security_group.db", ] } output "alb_dns_name" { value = "${aws_alb.default.dns_name}" }
-
ecs.tf
variable "app-repo" { default = "djample-app" } variable "nginx-repo" { default = "djample-nginx" } data "aws_ecr_repository" "app" { name = "${var.app-repo}" } data "aws_ecr_repository" "nginx" { name = "${var.nginx-repo}" } data "template_file" "djample-web-containers" { template = "${file("task-definitions/djample-web.json")}" vars = { db_host = "${aws_db_instance.default.endpoint}" db_port = "5432" db_name = "${var.db_name}" db_user = "${var.db_user}" db_password = "${var.db_password}" image_app = "${data.aws_ecr_repository.app.repository_url}" image_nginx = "${data.aws_ecr_repository.nginx.repository_url}" } } resource "aws_ecs_task_definition" "web" { family = "djample-web-task" network_mode = "awsvpc" cpu = 256 memory = 512 requires_compatibilities = ["FARGATE"] container_definitions = "${data.template_file.djample-web-containers.rendered}" task_role_arn = "${aws_iam_role.default.arn}" execution_role_arn = "${aws_iam_role.default.arn}" } resource "aws_ecs_cluster" "default" { name = "djample-cluster" } resource "aws_ecs_service" "web" { name = "djample-web-service" launch_type = "FARGATE" cluster = "${aws_ecs_cluster.default.id}" task_definition = "${aws_ecs_task_definition.web.arn}" desired_count = 1 network_configuration { security_groups = [ "${aws_security_group.web.id}", ] subnets = [ "${aws_subnet.default1.id}", "${aws_subnet.default2.id}", "${aws_subnet.default3.id}", ] assign_public_ip = true } load_balancer { target_group_arn = "${aws_alb_target_group.default.arn}" container_name = "djample-nginx" container_port = 80 } }
-
djample-web.json
[ { "portMappings": [ { "hostPort": 3031, "protocol": "tcp", "containerPort": 3031 } ], "environment": [ { "name": "DJANGO_DATABASES__default__ENGINE", "value": "django.db.backends.postgresql" }, { "name": "DJANGO_DATABASES__default__HOST", "value": "${db_host}" }, { "name": "DJANGO_DATABASES__default__NAME", "value": "${db_name}" }, { "name": "DJANGO_DATABASES__default__PASSWORD", "value": "${db_password}" }, { "name": "DJANGO_DATABASES__default__PORT", "value": "${db_port}" }, { "name": "DJANGO_DATABASES__default__USER", "value": "${db_user}" } ], "image": "${image_app}", "essential": true, "name": "djample-app" }, { "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ], "environment": [], "image": "${image_nginx}", "essential": true, "name": "djample-nginx" } ]
-
- info
PostgreSQL
を指定してaws_db_instance.db: Error creating DB Instance: InvalidParameterValue: Invalid DB engine
と言われたらpostgres
を指定する- 今回利用するユーザが属するグループは
AdministratorAccess
ポリシーを持っているものとします。
初期化デプロイ
まずは初回のみ必要なデプロイを行います。 初回しか必要ないので手動でもいいと思いますが、今回は敢えて Terraform でやります。
Dockerリポジトリの作成 (とイメージのPush) だけです。
何故かDNS認証がうまくいかなかったので証明書は作りませんでした..
$ cd init/
# バックエンドの初期化
$ terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (1.54.0)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 1.54"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$ terraform apply -var "access_key=XXXXXXXXXXXXXXXXXXXX" -var "secret_key=YYYYYYYYYYYYYYYYYYYYYYYYYYYY"
aws_ecr_repository.nginx-repo: Refreshing state... (ID: djample-nginx)
aws_ecr_repository.app-repo: Refreshing state... (ID: djample-app)
aws_acm_certificate.cert: Refreshing state... (ID: arn:aws:acm:us-west-2:XXXXXXXXXXXX:cert...e/322dc8e9-26d1-41ef-ba64-53da42641ebe)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ aws_ecr_repository.app-repo
id: <computed>
arn: <computed>
name: "djample-app"
registry_id: <computed>
repository_url: <computed>
+ aws_ecr_repository.nginx-repo
id: <computed>
arn: <computed>
name: "djample-nginx"
registry_id: <computed>
repository_url: <computed>
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_ecr_repository.app-repo: Creating...
arn: "" => "<computed>"
name: "" => "djample-app"
registry_id: "" => "<computed>"
repository_url: "" => "<computed>"
aws_ecr_repository.nginx-repo: Creating...
arn: "" => "<computed>"
name: "" => "djample-nginx"
registry_id: "" => "<computed>"
repository_url: "" => "<computed>"
aws_ecr_repository.app-repo: Creation complete after 2s (ID: djample-app)
aws_ecr_repository.nginx-repo: Creation complete after 2s (ID: djample-nginx)
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
app-repo-url = XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app
nginx-repo-url = XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx
続いて、イメージと作成したリポジトリを紐づけ、PUSHします (ここは前回と同様です)
# docker に AWS認証情報を登録
$ $(aws --profile djample ecr get-login --no-include-email --region us-west-2)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
# リポジトリとイメージを紐付けてPUSHする
$ docker tag djample-app:latest XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app:latest
$ docker push XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app:latest
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app]
6836c8c88b45: Pushed
615d45681fa6: Pushed
15b6883e063f: Pushed
c5eee45b9f53: Pushed
8e771df6e17b: Pushed
dab2c9255521: Pushed
016210a3d295: Pushed
ef7a479213de: Pushed
374f3534200b: Pushed
8fec0692e6a1: Pushed
219d5a9f3bbe: Pushed
67b9b2a215ea: Pushed
956940650d5d: Pushed
latest: digest: sha256:6e78416aee66fd997e9d3eacb15ee602a14dba76a72fcb0dbc100dcd39f4c6f8 size: 3031
# Nginx も同様にやる
$ docker tag djample-nginx:latest XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx:latest
$ docker push XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx:latest
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx]
f514a6aae98f: Pushed
82544808b996: Pushed
942f421fc8f4: Pushed
67f95e015a50: Pushed
3803fdb990e6: Pushed
5871f1dd9014: Pushed
4cc529071e3b: Pushed
cdb3f9544e4c: Pushed
latest: digest: sha256:8b467500656e208d712a8ae7cb25f13896cf81e207d891469e9848b8da6f7d93 size: 1987
アプリをデプロイする
最後にアプリをデプロイします
$ cd ../
# バックエンドの初期化
$ terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (1.54.0)...
- Downloading plugin for provider "template" (1.0.0)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 1.54"
* provider.template: version = "~> 1.0"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$ terraform apply -var "access_key=XXXXXXXXXXXXXXXXXXXXXXXX" -var "secret_key=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
data.aws_ecr_repository.nginx: Refreshing state...
data.aws_ecr_repository.app: Refreshing state...
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
<= data.template_file.djample-web-containers
id: <computed>
rendered: <computed>
template: "[\n {\n \"portMappings\": [\n {\n \"hostPort\": 3031,\n \"protocol\": \"tcp\",\n \"containerPort\": 3031\n }\n ],\n \"environment\": [\n {\n \"name\": \"DJANGO_DATABASES__default__ENGINE\",\n \"value\": \"django.db.backends.postgresql\"\n },\n {\n \"name\": \"DJANGO_DATABASES__default__HOST\",\n \"value\": \"${db_host}\"\n },\n {\n \"name\": \"DJANGO_DATABASES__default__NAME\",\n \"value\": \"${db_name}\"\n },\n {\n \"name\": \"DJANGO_DATABASES__default__PASSWORD\",\n \"value\": \"${db_password}\"\n },\n {\n \"name\": \"DJANGO_DATABASES__default__PORT\",\n \"value\": \"${db_port}\"\n },\n {\n \"name\": \"DJANGO_DATABASES__default__USER\",\n \"value\": \"${db_user}\"\n }\n ],\n \"image\": \"${image_app}\",\n \"essential\": true,\n \"name\": \"djample-app\"\n },\n {\n \"portMappings\": [\n {\n \"hostPort\": 80,\n \"protocol\": \"tcp\",\n \"containerPort\": 80\n }\n ],\n \"environment\": [],\n \"image\": \"${image_nginx}\",\n \"essential\": true,\n \"name\": \"djample-nginx\"\n }\n]"
vars.%: <computed>
+ aws_alb.default
id: <computed>
access_logs.#: <computed>
arn: <computed>
arn_suffix: <computed>
dns_name: <computed>
enable_deletion_protection: "false"
enable_http2: "true"
idle_timeout: "60"
internal: "false"
ip_address_type: <computed>
load_balancer_type: "application"
name: "djample-alb"
security_groups.#: <computed>
subnet_mapping.#: <computed>
subnets.#: <computed>
vpc_id: <computed>
zone_id: <computed>
+ aws_alb_listener.http
id: <computed>
arn: <computed>
default_action.#: "1"
default_action.0.order: <computed>
default_action.0.target_group_arn: "${aws_alb_target_group.default.arn}"
default_action.0.type: "forward"
load_balancer_arn: "${aws_alb.default.arn}"
port: "80"
protocol: "HTTP"
ssl_policy: <computed>
+ aws_alb_target_group.default
id: <computed>
arn: <computed>
arn_suffix: <computed>
deregistration_delay: "300"
health_check.#: "1"
health_check.0.healthy_threshold: "3"
health_check.0.interval: "30"
health_check.0.matcher: <computed>
health_check.0.path: "/"
health_check.0.port: "traffic-port"
health_check.0.protocol: "HTTP"
health_check.0.timeout: <computed>
health_check.0.unhealthy_threshold: "3"
name: "djample-target-group"
port: "80"
protocol: "HTTP"
proxy_protocol_v2: "false"
slow_start: "0"
stickiness.#: <computed>
target_type: "ip"
vpc_id: "${aws_vpc.default.id}"
+ aws_db_instance.default
id: <computed>
address: <computed>
allocated_storage: "10"
apply_immediately: <computed>
arn: <computed>
auto_minor_version_upgrade: "true"
availability_zone: <computed>
backup_retention_period: <computed>
backup_window: <computed>
ca_cert_identifier: <computed>
character_set_name: <computed>
copy_tags_to_snapshot: "false"
db_subnet_group_name: "test-db-subnet"
endpoint: <computed>
engine: "postgres"
engine_version: "10.4"
hosted_zone_id: <computed>
identifier: "djample"
identifier_prefix: <computed>
instance_class: "db.t2.micro"
kms_key_id: <computed>
license_model: <computed>
maintenance_window: <computed>
monitoring_interval: "0"
monitoring_role_arn: <computed>
multi_az: <computed>
name: "djampledb"
option_group_name: <computed>
parameter_group_name: "${aws_db_parameter_group.default.id}"
password: <sensitive>
port: <computed>
publicly_accessible: "false"
replicas.#: <computed>
resource_id: <computed>
skip_final_snapshot: "true"
status: <computed>
storage_type: "gp2"
timezone: <computed>
username: "djampleuser"
vpc_security_group_ids.#: <computed>
+ aws_db_parameter_group.default
id: <computed>
arn: <computed>
description: " "djample postgresql parameter""
family: "postgres10"
name: "djample-parameter-group"
name_prefix: <computed>
parameter.#: "1"
parameter.3863681210.apply_method: "immediate"
parameter.3863681210.name: "log_min_duration_statement"
parameter.3863681210.value: "100"
+ aws_db_subnet_group.default
id: <computed>
arn: <computed>
description: " "test db subnet""
name: "test-db-subnet"
name_prefix: <computed>
subnet_ids.#: <computed>
+ aws_ecs_cluster.default
id: <computed>
arn: <computed>
name: "djample-cluster"
+ aws_ecs_service.web
id: <computed>
cluster: "${aws_ecs_cluster.default.id}"
deployment_maximum_percent: "200"
deployment_minimum_healthy_percent: "100"
desired_count: "1"
enable_ecs_managed_tags: "false"
iam_role: <computed>
launch_type: "FARGATE"
load_balancer.#: "1"
load_balancer.~563643602.container_name: "djample-nginx"
load_balancer.~563643602.container_port: "80"
load_balancer.~563643602.elb_name: ""
load_balancer.~563643602.target_group_arn: "${aws_alb_target_group.default.arn}"
name: "djample-web-service"
network_configuration.#: "1"
network_configuration.0.assign_public_ip: "true"
network_configuration.0.security_groups.#: <computed>
network_configuration.0.subnets.#: <computed>
scheduling_strategy: "REPLICA"
task_definition: "${aws_ecs_task_definition.web.arn}"
+ aws_ecs_task_definition.web
id: <computed>
arn: <computed>
container_definitions: "${data.template_file.djample-web-containers.rendered}"
cpu: "256"
execution_role_arn: "${aws_iam_role.default.arn}"
family: "djample-web-task"
memory: "512"
network_mode: "awsvpc"
requires_compatibilities.#: "1"
requires_compatibilities.3072437307: "FARGATE"
revision: <computed>
task_role_arn: "${aws_iam_role.default.arn}"
+ aws_iam_role.default
id: <computed>
arn: <computed>
assume_role_policy: "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Service\": \"ecs-tasks.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRole\"\n }\n ]\n}\n"
create_date: <computed>
force_detach_policies: "false"
max_session_duration: "3600"
name: "assume_role"
path: "/"
unique_id: <computed>
+ aws_iam_role_policy.default
id: <computed>
name: "assume_role_policy"
policy: "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"*\",\n \"Resource\": \"*\"\n }\n ]\n}\n"
role: "${aws_iam_role.default.id}"
+ aws_internet_gateway.default
id: <computed>
owner_id: <computed>
tags.%: "1"
tags.Name: "djample-igw"
vpc_id: "${aws_vpc.default.id}"
+ aws_route_table.default
id: <computed>
owner_id: <computed>
propagating_vgws.#: <computed>
route.#: "1"
route.~570683813.cidr_block: "0.0.0.0/0"
route.~570683813.egress_only_gateway_id: ""
route.~570683813.gateway_id: "${aws_internet_gateway.default.id}"
route.~570683813.instance_id: ""
route.~570683813.ipv6_cidr_block: ""
route.~570683813.nat_gateway_id: ""
route.~570683813.network_interface_id: ""
route.~570683813.transit_gateway_id: ""
route.~570683813.vpc_peering_connection_id: ""
tags.%: "1"
tags.Name: "main"
vpc_id: "${aws_vpc.default.id}"
+ aws_route_table_association.a1
id: <computed>
route_table_id: "${aws_route_table.default.id}"
subnet_id: "${aws_subnet.default1.id}"
+ aws_route_table_association.a2
id: <computed>
route_table_id: "${aws_route_table.default.id}"
subnet_id: "${aws_subnet.default2.id}"
+ aws_route_table_association.a3
id: <computed>
route_table_id: "${aws_route_table.default.id}"
subnet_id: "${aws_subnet.default3.id}"
+ aws_security_group.db
id: <computed>
arn: <computed>
description: " "Allow traffic for db""
egress.#: "1"
egress.482069346.cidr_blocks.#: "1"
egress.482069346.cidr_blocks.0: "0.0.0.0/0"
egress.482069346.description: ""
egress.482069346.from_port: "0"
egress.482069346.ipv6_cidr_blocks.#: "0"
egress.482069346.prefix_list_ids.#: "0"
egress.482069346.protocol: "-1"
egress.482069346.security_groups.#: "0"
egress.482069346.self: "false"
egress.482069346.to_port: "0"
ingress.#: "1"
ingress.~2994424545.cidr_blocks.#: "0"
ingress.~2994424545.description: ""
ingress.~2994424545.from_port: "5432"
ingress.~2994424545.ipv6_cidr_blocks.#: "0"
ingress.~2994424545.prefix_list_ids.#: "0"
ingress.~2994424545.protocol: "tcp"
ingress.~2994424545.security_groups.#: <computed>
ingress.~2994424545.self: "false"
ingress.~2994424545.to_port: "5432"
name: "djample-db-sg"
owner_id: <computed>
revoke_rules_on_delete: "false"
vpc_id: "${aws_vpc.default.id}"
+ aws_security_group.web
id: <computed>
arn: <computed>
description: " "Allow traffic for web""
egress.#: "1"
egress.482069346.cidr_blocks.#: "1"
egress.482069346.cidr_blocks.0: "0.0.0.0/0"
egress.482069346.description: ""
egress.482069346.from_port: "0"
egress.482069346.ipv6_cidr_blocks.#: "0"
egress.482069346.prefix_list_ids.#: "0"
egress.482069346.protocol: "-1"
egress.482069346.security_groups.#: "0"
egress.482069346.self: "false"
egress.482069346.to_port: "0"
ingress.#: "2"
ingress.2214680975.cidr_blocks.#: "1"
ingress.2214680975.cidr_blocks.0: "0.0.0.0/0"
ingress.2214680975.description: ""
ingress.2214680975.from_port: "80"
ingress.2214680975.ipv6_cidr_blocks.#: "0"
ingress.2214680975.prefix_list_ids.#: "0"
ingress.2214680975.protocol: "tcp"
ingress.2214680975.security_groups.#: "0"
ingress.2214680975.self: "false"
ingress.2214680975.to_port: "80"
ingress.2617001939.cidr_blocks.#: "1"
ingress.2617001939.cidr_blocks.0: "0.0.0.0/0"
ingress.2617001939.description: ""
ingress.2617001939.from_port: "443"
ingress.2617001939.ipv6_cidr_blocks.#: "0"
ingress.2617001939.prefix_list_ids.#: "0"
ingress.2617001939.protocol: "tcp"
ingress.2617001939.security_groups.#: "0"
ingress.2617001939.self: "false"
ingress.2617001939.to_port: "443"
name: "djample-web-sg"
owner_id: <computed>
revoke_rules_on_delete: "false"
vpc_id: "${aws_vpc.default.id}"
+ aws_subnet.default1
id: <computed>
arn: <computed>
assign_ipv6_address_on_creation: "false"
availability_zone: "us-west-2a"
availability_zone_id: <computed>
cidr_block: "10.0.1.0/24"
ipv6_cidr_block: <computed>
ipv6_cidr_block_association_id: <computed>
map_public_ip_on_launch: "false"
owner_id: <computed>
vpc_id: "${aws_vpc.default.id}"
+ aws_subnet.default2
id: <computed>
arn: <computed>
assign_ipv6_address_on_creation: "false"
availability_zone: "us-west-2b"
availability_zone_id: <computed>
cidr_block: "10.0.2.0/24"
ipv6_cidr_block: <computed>
ipv6_cidr_block_association_id: <computed>
map_public_ip_on_launch: "false"
owner_id: <computed>
vpc_id: "${aws_vpc.default.id}"
+ aws_subnet.default3
id: <computed>
arn: <computed>
assign_ipv6_address_on_creation: "false"
availability_zone: "us-west-2c"
availability_zone_id: <computed>
cidr_block: "10.0.3.0/24"
ipv6_cidr_block: <computed>
ipv6_cidr_block_association_id: <computed>
map_public_ip_on_launch: "false"
owner_id: <computed>
vpc_id: "${aws_vpc.default.id}"
+ aws_vpc.default
id: <computed>
arn: <computed>
assign_generated_ipv6_cidr_block: "false"
cidr_block: "10.0.0.0/16"
default_network_acl_id: <computed>
default_route_table_id: <computed>
default_security_group_id: <computed>
dhcp_options_id: <computed>
enable_classiclink: <computed>
enable_classiclink_dns_support: <computed>
enable_dns_hostnames: <computed>
enable_dns_support: "true"
instance_tenancy: "default"
ipv6_association_id: <computed>
ipv6_cidr_block: <computed>
main_route_table_id: <computed>
owner_id: <computed>
Plan: 22 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_iam_role.default: Creating...
arn: "" => "<computed>"
assume_role_policy: "" => "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Service\": \"ecs-tasks.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRole\"\n }\n ]\n}\n"
create_date: "" => "<computed>"
force_detach_policies: "" => "false"
max_session_duration: "" => "3600"
name: "" => "assume_role"
path: "" => "/"
unique_id: "" => "<computed>"
aws_ecs_cluster.default: Creating...
arn: "" => "<computed>"
name: "" => "djample-cluster"
aws_db_parameter_group.default: Creating...
arn: "" => "<computed>"
description: "" => "djample postgresql parameter"
family: "" => "postgres10"
name: "" => "djample-parameter-group"
name_prefix: "" => "<computed>"
parameter.#: "" => "1"
parameter.3863681210.apply_method: "" => "immediate"
parameter.3863681210.name: "" => "log_min_duration_statement"
parameter.3863681210.value: "" => "100"
aws_vpc.default: Creating...
arn: "" => "<computed>"
assign_generated_ipv6_cidr_block: "" => "false"
cidr_block: "" => "10.0.0.0/16"
default_network_acl_id: "" => "<computed>"
default_route_table_id: "" => "<computed>"
default_security_group_id: "" => "<computed>"
dhcp_options_id: "" => "<computed>"
enable_classiclink: "" => "<computed>"
enable_classiclink_dns_support: "" => "<computed>"
enable_dns_hostnames: "" => "<computed>"
enable_dns_support: "" => "true"
instance_tenancy: "" => "default"
ipv6_association_id: "" => "<computed>"
ipv6_cidr_block: "" => "<computed>"
main_route_table_id: "" => "<computed>"
owner_id: "" => "<computed>"
aws_ecs_cluster.default: Creation complete after 3s (ID: arn:aws:ecs:us-west-2:XXXXXXXXXXXX:cluster/djample-cluster)
aws_iam_role.default: Creation complete after 3s (ID: assume_role)
aws_iam_role_policy.default: Creating...
name: "" => "assume_role_policy"
policy: "" => "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"*\",\n \"Resource\": \"*\"\n }\n ]\n}\n"
role: "" => "assume_role"
aws_iam_role_policy.default: Creation complete after 1s (ID: assume_role:assume_role_policy)
aws_db_parameter_group.default: Creation complete after 7s (ID: djample-parameter-group)
aws_vpc.default: Creation complete after 10s (ID: vpc-06346176fa149789f)
aws_subnet.default3: Creating...
arn: "" => "<computed>"
assign_ipv6_address_on_creation: "" => "false"
availability_zone: "" => "us-west-2c"
availability_zone_id: "" => "<computed>"
cidr_block: "" => "10.0.3.0/24"
ipv6_cidr_block: "" => "<computed>"
ipv6_cidr_block_association_id: "" => "<computed>"
map_public_ip_on_launch: "" => "false"
owner_id: "" => "<computed>"
vpc_id: "" => "vpc-06346176fa149789f"
aws_subnet.default1: Creating...
arn: "" => "<computed>"
assign_ipv6_address_on_creation: "" => "false"
availability_zone: "" => "us-west-2a"
availability_zone_id: "" => "<computed>"
cidr_block: "" => "10.0.1.0/24"
ipv6_cidr_block: "" => "<computed>"
ipv6_cidr_block_association_id: "" => "<computed>"
map_public_ip_on_launch: "" => "false"
owner_id: "" => "<computed>"
vpc_id: "" => "vpc-06346176fa149789f"
aws_subnet.default2: Creating...
arn: "" => "<computed>"
assign_ipv6_address_on_creation: "" => "false"
availability_zone: "" => "us-west-2b"
availability_zone_id: "" => "<computed>"
cidr_block: "" => "10.0.2.0/24"
ipv6_cidr_block: "" => "<computed>"
ipv6_cidr_block_association_id: "" => "<computed>"
map_public_ip_on_launch: "" => "false"
owner_id: "" => "<computed>"
vpc_id: "" => "vpc-06346176fa149789f"
aws_internet_gateway.default: Creating...
owner_id: "" => "<computed>"
tags.%: "0" => "1"
tags.Name: "" => "djample-igw"
vpc_id: "" => "vpc-06346176fa149789f"
aws_security_group.web: Creating...
arn: "" => "<computed>"
description: "" => "Allow traffic for web"
egress.#: "" => "1"
egress.482069346.cidr_blocks.#: "" => "1"
egress.482069346.cidr_blocks.0: "" => "0.0.0.0/0"
egress.482069346.description: "" => ""
egress.482069346.from_port: "" => "0"
egress.482069346.ipv6_cidr_blocks.#: "" => "0"
egress.482069346.prefix_list_ids.#: "" => "0"
egress.482069346.protocol: "" => "-1"
egress.482069346.security_groups.#: "" => "0"
egress.482069346.self: "" => "false"
egress.482069346.to_port: "" => "0"
ingress.#: "" => "2"
ingress.2214680975.cidr_blocks.#: "" => "1"
ingress.2214680975.cidr_blocks.0: "" => "0.0.0.0/0"
ingress.2214680975.description: "" => ""
ingress.2214680975.from_port: "" => "80"
ingress.2214680975.ipv6_cidr_blocks.#: "" => "0"
ingress.2214680975.prefix_list_ids.#: "" => "0"
ingress.2214680975.protocol: "" => "tcp"
ingress.2214680975.security_groups.#: "" => "0"
ingress.2214680975.self: "" => "false"
ingress.2214680975.to_port: "" => "80"
ingress.2617001939.cidr_blocks.#: "" => "1"
ingress.2617001939.cidr_blocks.0: "" => "0.0.0.0/0"
ingress.2617001939.description: "" => ""
ingress.2617001939.from_port: "" => "443"
ingress.2617001939.ipv6_cidr_blocks.#: "" => "0"
ingress.2617001939.prefix_list_ids.#: "" => "0"
ingress.2617001939.protocol: "" => "tcp"
ingress.2617001939.security_groups.#: "" => "0"
ingress.2617001939.self: "" => "false"
ingress.2617001939.to_port: "" => "443"
name: "" => "djample-web-sg"
owner_id: "" => "<computed>"
revoke_rules_on_delete: "" => "false"
vpc_id: "" => "vpc-06346176fa149789f"
aws_alb_target_group.default: Creating...
arn: "" => "<computed>"
arn_suffix: "" => "<computed>"
deregistration_delay: "" => "300"
health_check.#: "" => "1"
health_check.0.healthy_threshold: "" => "3"
health_check.0.interval: "" => "30"
health_check.0.matcher: "" => "<computed>"
health_check.0.path: "" => "/"
health_check.0.port: "" => "traffic-port"
health_check.0.protocol: "" => "HTTP"
health_check.0.timeout: "" => "<computed>"
health_check.0.unhealthy_threshold: "" => "3"
name: "" => "djample-target-group"
port: "" => "80"
protocol: "" => "HTTP"
proxy_protocol_v2: "" => "false"
slow_start: "" => "0"
stickiness.#: "" => "<computed>"
target_type: "" => "ip"
vpc_id: "" => "vpc-06346176fa149789f"
aws_subnet.default1: Creation complete after 2s (ID: subnet-08022d6c8417edca8)
aws_subnet.default3: Creation complete after 2s (ID: subnet-0b2b0c2e4ae1f2a66)
aws_subnet.default2: Creation complete after 2s (ID: subnet-09d44ac8bf7c95769)
aws_db_subnet_group.default: Creating...
arn: "" => "<computed>"
description: "" => "test db subnet"
name: "" => "test-db-subnet"
name_prefix: "" => "<computed>"
subnet_ids.#: "" => "3"
subnet_ids.2370142301: "" => "subnet-0b2b0c2e4ae1f2a66"
subnet_ids.2494457805: "" => "subnet-09d44ac8bf7c95769"
subnet_ids.3574656835: "" => "subnet-08022d6c8417edca8"
aws_internet_gateway.default: Creation complete after 4s (ID: igw-04a6eb2ff12954c0e)
aws_route_table.default: Creating...
owner_id: "" => "<computed>"
propagating_vgws.#: "" => "<computed>"
route.#: "" => "1"
route.2780151265.cidr_block: "" => "0.0.0.0/0"
route.2780151265.egress_only_gateway_id: "" => ""
route.2780151265.gateway_id: "" => "igw-04a6eb2ff12954c0e"
route.2780151265.instance_id: "" => ""
route.2780151265.ipv6_cidr_block: "" => ""
route.2780151265.nat_gateway_id: "" => ""
route.2780151265.network_interface_id: "" => ""
route.2780151265.transit_gateway_id: "" => ""
route.2780151265.vpc_peering_connection_id: "" => ""
tags.%: "" => "1"
tags.Name: "" => "main"
vpc_id: "" => "vpc-06346176fa149789f"
aws_alb_target_group.default: Creation complete after 4s (ID: arn:aws:elasticloadbalancing:us-west-2:.../djample-target-group/0cf7190ec2060917)
aws_db_subnet_group.default: Creation complete after 3s (ID: test-db-subnet)
aws_security_group.web: Creation complete after 6s (ID: sg-085110806fab80ae0)
aws_security_group.db: Creating...
arn: "" => "<computed>"
description: "" => "Allow traffic for db"
egress.#: "" => "1"
egress.482069346.cidr_blocks.#: "" => "1"
egress.482069346.cidr_blocks.0: "" => "0.0.0.0/0"
egress.482069346.description: "" => ""
egress.482069346.from_port: "" => "0"
egress.482069346.ipv6_cidr_blocks.#: "" => "0"
egress.482069346.prefix_list_ids.#: "" => "0"
egress.482069346.protocol: "" => "-1"
egress.482069346.security_groups.#: "" => "0"
egress.482069346.self: "" => "false"
egress.482069346.to_port: "" => "0"
ingress.#: "" => "1"
ingress.1726492711.cidr_blocks.#: "" => "0"
ingress.1726492711.description: "" => ""
ingress.1726492711.from_port: "" => "5432"
ingress.1726492711.ipv6_cidr_blocks.#: "" => "0"
ingress.1726492711.prefix_list_ids.#: "" => "0"
ingress.1726492711.protocol: "" => "tcp"
ingress.1726492711.security_groups.#: "" => "1"
ingress.1726492711.security_groups.2467559028: "" => "sg-085110806fab80ae0"
ingress.1726492711.self: "" => "false"
ingress.1726492711.to_port: "" => "5432"
name: "" => "djample-db-sg"
owner_id: "" => "<computed>"
revoke_rules_on_delete: "" => "false"
vpc_id: "" => "vpc-06346176fa149789f"
aws_alb.default: Creating...
access_logs.#: "" => "<computed>"
arn: "" => "<computed>"
arn_suffix: "" => "<computed>"
dns_name: "" => "<computed>"
enable_deletion_protection: "" => "false"
enable_http2: "" => "true"
idle_timeout: "" => "60"
internal: "" => "false"
ip_address_type: "" => "<computed>"
load_balancer_type: "" => "application"
name: "" => "djample-alb"
security_groups.#: "" => "1"
security_groups.2467559028: "" => "sg-085110806fab80ae0"
subnet_mapping.#: "" => "<computed>"
subnets.#: "" => "3"
subnets.2370142301: "" => "subnet-0b2b0c2e4ae1f2a66"
subnets.2494457805: "" => "subnet-09d44ac8bf7c95769"
subnets.3574656835: "" => "subnet-08022d6c8417edca8"
vpc_id: "" => "<computed>"
zone_id: "" => "<computed>"
aws_route_table.default: Creation complete after 4s (ID: rtb-0948f223bd8f3791d)
aws_route_table_association.a1: Creating...
route_table_id: "" => "rtb-0948f223bd8f3791d"
subnet_id: "" => "subnet-08022d6c8417edca8"
aws_route_table_association.a2: Creating...
route_table_id: "" => "rtb-0948f223bd8f3791d"
subnet_id: "" => "subnet-09d44ac8bf7c95769"
aws_route_table_association.a3: Creating...
route_table_id: "" => "rtb-0948f223bd8f3791d"
subnet_id: "" => "subnet-0b2b0c2e4ae1f2a66"
aws_route_table_association.a1: Creation complete after 0s (ID: rtbassoc-0b66b625616f40b40)
aws_route_table_association.a2: Creation complete after 1s (ID: rtbassoc-0e50b908e3f8214db)
aws_route_table_association.a3: Creation complete after 1s (ID: rtbassoc-02dea821a448a1ac6)
aws_security_group.db: Creation complete after 7s (ID: sg-05442bb3a6ccef9cc)
aws_db_instance.default: Creating...
address: "" => "<computed>"
allocated_storage: "" => "10"
apply_immediately: "" => "<computed>"
arn: "" => "<computed>"
auto_minor_version_upgrade: "" => "true"
availability_zone: "" => "<computed>"
backup_retention_period: "" => "<computed>"
backup_window: "" => "<computed>"
ca_cert_identifier: "" => "<computed>"
character_set_name: "" => "<computed>"
copy_tags_to_snapshot: "" => "false"
db_subnet_group_name: "" => "test-db-subnet"
endpoint: "" => "<computed>"
engine: "" => "postgres"
engine_version: "" => "10.4"
hosted_zone_id: "" => "<computed>"
identifier: "" => "djample"
identifier_prefix: "" => "<computed>"
instance_class: "" => "db.t2.micro"
kms_key_id: "" => "<computed>"
license_model: "" => "<computed>"
maintenance_window: "" => "<computed>"
monitoring_interval: "" => "0"
monitoring_role_arn: "" => "<computed>"
multi_az: "" => "<computed>"
name: "" => "djampledb"
option_group_name: "" => "<computed>"
parameter_group_name: "" => "djample-parameter-group"
password: "<sensitive>" => "<sensitive>"
port: "" => "<computed>"
publicly_accessible: "" => "false"
replicas.#: "" => "<computed>"
resource_id: "" => "<computed>"
skip_final_snapshot: "" => "true"
status: "" => "<computed>"
storage_type: "" => "gp2"
timezone: "" => "<computed>"
username: "" => "djampleuser"
vpc_security_group_ids.#: "" => "1"
vpc_security_group_ids.1275660647: "" => "sg-05442bb3a6ccef9cc"
aws_alb.default: Still creating... (10s elapsed)
aws_db_instance.default: Still creating... (10s elapsed)
aws_alb.default: Still creating... (20s elapsed)
aws_db_instance.default: Still creating... (20s elapsed)
aws_alb.default: Still creating... (30s elapsed)
aws_db_instance.default: Still creating... (30s elapsed)
aws_alb.default: Still creating... (40s elapsed)
aws_db_instance.default: Still creating... (40s elapsed)
aws_alb.default: Still creating... (50s elapsed)
aws_db_instance.default: Still creating... (50s elapsed)
aws_alb.default: Still creating... (1m0s elapsed)
aws_db_instance.default: Still creating... (1m0s elapsed)
aws_alb.default: Still creating... (1m10s elapsed)
aws_db_instance.default: Still creating... (1m10s elapsed)
aws_alb.default: Still creating... (1m20s elapsed)
aws_db_instance.default: Still creating... (1m20s elapsed)
aws_alb.default: Still creating... (1m30s elapsed)
aws_db_instance.default: Still creating... (1m30s elapsed)
aws_alb.default: Still creating... (1m40s elapsed)
aws_db_instance.default: Still creating... (1m40s elapsed)
aws_alb.default: Still creating... (1m50s elapsed)
aws_db_instance.default: Still creating... (1m50s elapsed)
aws_alb.default: Still creating... (2m0s elapsed)
aws_db_instance.default: Still creating... (2m0s elapsed)
aws_alb.default: Still creating... (2m10s elapsed)
aws_db_instance.default: Still creating... (2m10s elapsed)
aws_alb.default: Still creating... (2m20s elapsed)
aws_db_instance.default: Still creating... (2m20s elapsed)
aws_alb.default: Still creating... (2m30s elapsed)
aws_db_instance.default: Still creating... (2m30s elapsed)
aws_alb.default: Still creating... (2m40s elapsed)
aws_db_instance.default: Still creating... (2m40s elapsed)
aws_alb.default: Still creating... (2m50s elapsed)
aws_db_instance.default: Still creating... (2m50s elapsed)
aws_alb.default: Still creating... (3m0s elapsed)
aws_db_instance.default: Still creating... (3m0s elapsed)
aws_alb.default: Still creating... (3m10s elapsed)
aws_db_instance.default: Still creating... (3m10s elapsed)
aws_alb.default: Still creating... (3m20s elapsed)
aws_db_instance.default: Still creating... (3m20s elapsed)
aws_alb.default: Still creating... (3m30s elapsed)
aws_alb.default: Creation complete after 3m36s (ID: arn:aws:elasticloadbalancing:us-west-2:...ancer/app/djample-alb/4046b85f0d60d20d)
aws_alb_listener.http: Creating...
arn: "" => "<computed>"
default_action.#: "" => "1"
default_action.0.order: "" => "<computed>"
default_action.0.target_group_arn: "" => "arn:aws:elasticloadbalancing:us-west-2:XXXXXXXXXXXX:targetgroup/djample-target-group/0cf7190ec2060917"
default_action.0.type: "" => "forward"
load_balancer_arn: "" => "arn:aws:elasticloadbalancing:us-west-2:XXXXXXXXXXXX:loadbalancer/app/djample-alb/4046b85f0d60d20d"
port: "" => "80"
protocol: "" => "HTTP"
ssl_policy: "" => "<computed>"
aws_db_instance.default: Still creating... (3m30s elapsed)
aws_alb_listener.http: Creation complete after 1s (ID: arn:aws:elasticloadbalancing:us-west-2:...-alb/4046b85f0d60d20d/c2bc0c68eafdb2a9)
aws_db_instance.default: Still creating... (3m40s elapsed)
aws_db_instance.default: Still creating... (3m50s elapsed)
aws_db_instance.default: Still creating... (4m0s elapsed)
aws_db_instance.default: Still creating... (4m10s elapsed)
aws_db_instance.default: Still creating... (4m20s elapsed)
aws_db_instance.default: Still creating... (4m30s elapsed)
aws_db_instance.default: Still creating... (4m40s elapsed)
aws_db_instance.default: Still creating... (4m50s elapsed)
aws_db_instance.default: Still creating... (5m0s elapsed)
aws_db_instance.default: Still creating... (5m10s elapsed)
aws_db_instance.default: Still creating... (5m20s elapsed)
aws_db_instance.default: Still creating... (5m30s elapsed)
aws_db_instance.default: Creation complete after 5m31s (ID: djample)
data.template_file.djample-web-containers: Refreshing state...
aws_ecs_task_definition.web: Creating...
arn: "" => "<computed>"
container_definitions: "" => "[{\"environment\":[{\"name\":\"DJANGO_DATABASES__default__ENGINE\",\"value\":\"django.db.backends.postgresql\"},{\"name\":\"DJANGO_DATABASES__default__HOST\",\"value\":\"djample.civihq7xgpb5.us-west-2.rds.amazonaws.com:5432\"},{\"name\":\"DJANGO_DATABASES__default__NAME\",\"value\":\"djampledb\"},{\"name\":\"DJANGO_DATABASES__default__PASSWORD\",\"value\":\"djamplepass\"},{\"name\":\"DJANGO_DATABASES__default__PORT\",\"value\":\"5432\"},{\"name\":\"DJANGO_DATABASES__default__USER\",\"value\":\"djampleuser\"}],\"essential\":true,\"image\":\"XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app\",\"name\":\"djample-app\",\"portMappings\":[{\"containerPort\":3031,\"hostPort\":3031,\"protocol\":\"tcp\"}]},{\"environment\":[],\"essential\":true,\"image\":\"XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx\",\"name\":\"djample-nginx\",\"portMappings\":[{\"containerPort\":80,\"hostPort\":80,\"protocol\":\"tcp\"}]}]"
cpu: "" => "256"
execution_role_arn: "" => "arn:aws:iam::XXXXXXXXXXXX:role/assume_role"
family: "" => "djample-web-task"
memory: "" => "512"
network_mode: "" => "awsvpc"
requires_compatibilities.#: "" => "1"
requires_compatibilities.3072437307: "" => "FARGATE"
revision: "" => "<computed>"
task_role_arn: "" => "arn:aws:iam::XXXXXXXXXXXX:role/assume_role"
aws_ecs_task_definition.web: Creation complete after 1s (ID: djample-web-task)
aws_ecs_service.web: Creating...
cluster: "" => "arn:aws:ecs:us-west-2:XXXXXXXXXXXX:cluster/djample-cluster"
deployment_maximum_percent: "" => "200"
deployment_minimum_healthy_percent: "" => "100"
desired_count: "" => "1"
enable_ecs_managed_tags: "" => "false"
iam_role: "" => "<computed>"
launch_type: "" => "FARGATE"
load_balancer.#: "" => "1"
load_balancer.2891655293.container_name: "" => "djample-nginx"
load_balancer.2891655293.container_port: "" => "80"
load_balancer.2891655293.elb_name: "" => ""
load_balancer.2891655293.target_group_arn: "" => "arn:aws:elasticloadbalancing:us-west-2:XXXXXXXXXXXX:targetgroup/djample-target-group/0cf7190ec2060917"
name: "" => "djample-web-service"
network_configuration.#: "" => "1"
network_configuration.0.assign_public_ip: "" => "true"
network_configuration.0.security_groups.#: "" => "1"
network_configuration.0.security_groups.2467559028: "" => "sg-085110806fab80ae0"
network_configuration.0.subnets.#: "" => "3"
network_configuration.0.subnets.2370142301: "" => "subnet-0b2b0c2e4ae1f2a66"
network_configuration.0.subnets.2494457805: "" => "subnet-09d44ac8bf7c95769"
network_configuration.0.subnets.3574656835: "" => "subnet-08022d6c8417edca8"
scheduling_strategy: "" => "REPLICA"
task_definition: "" => "arn:aws:ecs:us-west-2:XXXXXXXXXXXX:task-definition/djample-web-task:17"
aws_ecs_service.web: Creation complete after 2s (ID: arn:aws:ecs:us-west-2:XXXXXXXXXXXX:service/djample-web-service)
Apply complete! Resources: 22 added, 0 changed, 0 destroyed.
Outputs:
alb_dns_name = djample-alb-1372101420.us-west-2.elb.amazonaws.com
output によって表示された ALBのホストにアクセスしてみると.. (もうないです)
表示されました! これにて一件落着。
その他参考
- AWS: Data Source: aws_ecr_repository - Terraform by HashiCorp
- AWS: aws_ecr_repository - Terraform by HashiCorp
- ecs — AWS CLI 1.16.81 Command Reference
- terraform で Amazon ECS 環境を弄る - ようへいの日々精進XP
- TerraformでECS環境の構築 - Carpe Diem
- 🎅terraformで理解する、"Fargate"と従来型ECSとの違い🎅 · hoshinotsuyoshi.com - 自由なブログだよ
- Oxalide/terraform-fargate-example: Example repository to run an ECS cluster on Fargate
- afedulov/terraform-fargate: Minimal example of deploying a Docker container to AWS Fargate using Terraform
- turnerlabs/terraform-ecs-fargate: A Terraform template used for provisioning web application stacks on AWS ECS Fargate
- TerraformでECSのawsvpcモードを使って各コンテナにPrivate IPを振る - Carpe Diem
- IAMロール徹底理解 〜 AssumeRoleの正体 | DevelopersIO