terraform 初心者メモ


# はじめに
最近、`terraform`を利用する機会が増えたので、メモ。

# Local Values
モジュール内に閉じて使える変数です。

- https://www.terraform.io/docs/configuration/locals.html

```
locals {
  version = {
    prd = 1.2
    stg = 1.0
  }
}

terraform_version = local.version[prd]
```

# Data Sources
Terraformの外部で定義された情報を利用する際に使います。

- https://www.terraform.io/docs/configuration/data-sources.html

```
data "aws_vpc" "vpc" {
  filter {
     name   = "tag:Name"
     values = ["sample-vpc"] # 外部で定義されたVPC
   }
}

locals {
  vpc_id = data.aws_vpc.vpc.id
}
```

# aws_security_group
セキュリティグループ。誰を・何を許可するか。

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group

```
# allow_tlsというセキュリティグループを作成し、そこに４４３番ポートのインバウンドルールを追加する

resource "aws_security_group" "allow_tls" {
  name        = "allow_tls"
  description = "Allow TLS inbound traffic"
  vpc_id      = aws_vpc.main.id

  # インバウンドルール
  ingress {
    description = "TLS from VPC"
    from_port   = 443 # 始まりポート (範囲の指定)
    to_port     = 443 # 終わりポート
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.main.cidr_block] # 許可するIPアドレス
  }

  # アウトバウンドルール
  # 何も許可しない設定でデフォルト設定(ALLOW ALL)を上書きしている
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1" # 全てのプロトコル
    cidr_blocks = ["0.0.0.0/0"] # 許可するIPアドレス
  }

  tags = {
    Name = "allow_tls"
  }
}
```

# aws_lb

ロードバランサ君

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb

```
resource "aws_lb" "test" {
  name               = "test-lb-tf"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.lb_sg.id] # ロードバランサーにアタッチするセキュリティーグループ
  subnets            = aws_subnet.public.*.id # 

  enable_deletion_protection = true

  access_logs {
    bucket  = aws_s3_bucket.lb_logs.bucket
    prefix  = "test-lb"
    enabled = true
  }
}
```

# aws_alb_listener
リスナーの作成(とALBとターゲットグループのひも付け)

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener

```
resource "aws_lb" "front_end" {
  # ...
}

resource "aws_lb_target_group" "front_end" {
  # ...
}

resource "aws_lb_listener" "front_end" {
  load_balancer_arn = aws_lb.front_end.arn # Amazon リソースネーム (ARN) 
  port              = "443" # lbが待ち受けるポート
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-2016-08" # HTTPS通信に必要
  certificate_arn   = "arn:aws:iam::187416307283:server-certificate/test_cert_rab3wuqwgja25ct3n4jdj2tzu4" # HTTPS通信に必要

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.front_end.arn
  }
}

```
 
# aws_alb_target_group

lbに利用するターゲットグループリソースを設定（インスタンス）

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group

```
resource "aws_lb_target_group" "test" {
  name     = "tf-example-lb-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}
```

# aws_route53_record
DNSの設定(ドメインとIPアドレスを紐づける)

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record

```
resource "aws_elb" "main" {
  name               = "foobar-terraform-elb"
  availability_zones = ["us-east-1c"]

  listener {
    instance_port     = 80
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
}

resource "aws_route53_record" "www" {
  zone_id = aws_route53_zone.primary.zone_id
  name    = "example.com"
  type    = "A" # lbの場合

  alias {
    name                   = aws_elb.main.dns_name # アタッチするlb
    zone_id                = aws_elb.main.zone_id
    evaluate_target_health = true
  }
}
```

# aws_s3_bucket
S3bucketの設定

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket

```
resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}
```

# aws_iam_user
iam userの設定

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user

```
resource "aws_iam_user" "lb" {
  name = "loadbalancer"
  path = "/system/"

  tags = {
    tag-key = "tag-value"
  }
}

# アクセスキーの発行
resource "aws_iam_access_key" "lb" {
  user = aws_iam_user.lb.name
}

# 付与する権限
resource "aws_iam_user_policy" "lb_ro" {
  name = "test"
  user = aws_iam_user.lb.name

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "ec2:Describe*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF
}
```

# aws_iam_role
iam roleの設定。アクセスキーの管理が不要 (流出リスク0) になるので、なるべくこちらを利用。

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role

```
resource "aws_iam_role" "test_role" {
  name = "test_role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = {
    tag-key = "tag-value"
  }
}
```

# aws_ecr_repository
docker imageの保管場所

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository

```
resource "aws_ecr_repository" "foo" {
  name                 = "bar"
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
    scan_on_push = true # imageの脆弱性チェック
  }
}
```


# aws_rds_cluster

RDSのインスタンスを管理するクラスタです。

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster


```
resource "aws_rds_cluster" "postgresql" {
  cluster_identifier      = "aurora-cluster-demo"
  engine                  = "aurora-postgresql"
  availability_zones      = ["us-west-2a", "us-west-2b", "us-west-2c"]
  database_name           = "mydb"
  master_username         = "foo"
  master_password         = "bar"
  backup_retention_period = 5
  preferred_backup_window = "07:00-09:00"
}
```


# aws_rds_cluster_instance

RDをクラスタに立てます。

- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance


```
resource "aws_rds_cluster_instance" "cluster_instances" {
  count              = 2
  identifier         = "aurora-cluster-demo-${count.index}"
  cluster_identifier = aws_rds_cluster.default.id
  instance_class     = "db.r4.large"
  engine             = aws_rds_cluster.default.engine
  engine_version     = aws_rds_cluster.default.engine_version
}

resource "aws_rds_cluster" "default" {
  cluster_identifier = "aurora-cluster-demo"
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
  database_name      = "mydb"
  master_username    = "foo"
  master_password    = "barbut8chars"
}
```