Terraform を使って Django を ECS (Fargate) に自動デプロイしてみた!

2019-01-07

前の記事 では、手動でデプロイしていましたが、 人間様がわざわざ AWSコンソールをポチポチやるなんて非効率ですし、いつかミスをするに決まっています。

そこで今回は Terraform を使って自動化してみることにします。

目次

準備 (Preparation)

必要なソフトウェアのインストールをします。

不要な場合は読み飛ばしてください。

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

ブラウザで見に行くと

index-tf.png

うーん、この

現時点では 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
参考

Terraform について (About Terraform)

Terraform についてよく知らなかったのですこし勉強しました。 すで詳しい人は次のセクションまで飛ばしてください。

重要なポイントを自分なりに整理すると以下のような感じでしょうか。

  • 変数は variable で宣言できる
    • 環境変数や、実行時引数、 module の引数から値を渡すことができる
    • 指定しない場合 default が使われる
  • Terraform の実行単位はディレクトリ
    • デフォルトでは カレントディレクトリに配置された .tf ファイルをすべて読みこんで実行する
    • 別のディレクトリを読み込む場合は module を使う。(今回は使ってないけど)
      • module で読み込んだディレクトリに 自動的に変数は引き継がれないので、引数として渡す必要がある
        • source, version, providers は別の用途で使うので渡せないし、 そもそも変数として使うべきではない
      • module で読み込んだディレクトリのリソース値を取得するには output を使う
  • <リソースの種類>.<リソース名>.<属性名> のようにして、リソースの属性値を参照できる
    • 作成されたリソースの属性も同様に参照できる
    • リソースの作成順は depends_on で制御できる

特に読み込みがディレクトリ単位というのはプログラミング言語とは違い 少し特殊な概念なのでちゃんと理解しましょう。

参考

ECSにアプリをデプロイする (Deploys an application on ECS)

Django を ECS(Fargate) に手動デプロイしたログ のシナリオと同様にサンプル用アプリケーションを ECS にデプロイします。

さて、単に Terraform を使ってデプロイすると言っても、 すべてのリソースを毎回作成する必要があるとは限りません。

例えば、ECR のコンテナリポジトリは一度作成すればよく、 すでにある状態で作成しようとするとエラーになります。

そこで「初回のみ作成するリソース」と「毎回作成するリソース」に わけ、前者は init というディレクトリの中に作成します。

このように、用途別にディレクトリを区切るのが Terraform のやり方のようです。

今回は次のような構成にしました。 わかりやすさ重視なので、ベストプラクティスには従っていません。

setup/
init/
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}"
}
init/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
  }
}
task-definitions/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"
  }
]

備考

  • PostgreSQL を指定して aws_db_instance.db: Error creating DB Instance: InvalidParameterValue: Invalid DB engine と言われたら postgres を指定する
  • 今回利用するユーザが属するグループは AdministratorAccess ポリシーを持っているものとします。

初期化デプロイ (Deploys for initiailzation)

まずは初回のみ必要なデプロイを行います。 初回しか必要ないので手動でもいいと思いますが、今回は敢えて 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

アプリをデプロイする(Deploys an app)

最後にアプリをデプロイします

$ 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のホストにアクセスしてみると.. (もうないです)

screenshot.png

表示されました! これにて一件落着。

その他参考