terraformでネットワークACL, セキュリティグループを作成

# 前回までのあらすじ
terraformでVPC, サブネットを作成する
https://qiita.com/sasshi_i/items/f4f65e18923d856be256

terraformでインターネットゲートウェイ, ルートテーブルを作る
https://qiita.com/sasshi_i/items/5edabca4fbaae7d4a833

# 環境
macOS Mojave 10.14.5
MacBook Pro, 13-inch, Early 2015
terraform v0.12.0
direnv 2.20.1

# 目標成果物
<img width="541" alt="スクリーンショット 2019-07-15 20.00.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324032/a6a160b0-bf3b-eaba-63f9-7367dddae2aa.png">

# github格納先
https://github.com/sasshi-i/terraform_ec2_rds

# 今回追記したプログラム
ネットワークACL

```/envs/modules/vpc/main.tf
resource "aws_default_network_acl" "qiita_default_acl" {
  default_network_acl_id = "${aws_vpc.qiita_vpc.default_network_acl_id}"

  egress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = "all"
    rule_no    = 101
    action     = "allow"
    ipv6_cidr_block = "::/0"
    from_port  = 0
    to_port    = 0
  }

  ingress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  ingress {
    protocol   = "all"
    rule_no    = 101
    action     = "allow"
    ipv6_cidr_block = "::/0"
    from_port  = 0
    to_port    = 0
  }

  tags = {
    Name = "qiita_acl"
  }
}
```

セキュリティグループ

```/envs/modules/vpc/main.tf
resource "aws_security_group" "alb" {
  name        = "qiita-${var.stage}-alb"
  description = "security group for ALB"
  vpc_id      = "${aws_vpc.qiita_vpc.id}"
  tags        = { 
    Name = "qiita-${var.stage}-alb" 
  }
}

resource "aws_security_group_rule" "alb-ingress-ipv4" {
  security_group_id = aws_security_group.alb.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
}

resource "aws_security_group_rule" "alb-ingress-ipv6" {
  security_group_id = aws_security_group.alb.id
  type              = "ingress"
  ipv6_cidr_blocks  = ["::/0"]
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
}

resource "aws_security_group_rule" "alb-egress-ipv4" {
  security_group_id = aws_security_group.alb.id
  type              = "egress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}

resource "aws_security_group_rule" "alb-egress-ipv6" {
  security_group_id = aws_security_group.alb.id
  type              = "egress"
  ipv6_cidr_blocks  = ["::/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}


resource "aws_security_group" "ec2" {
  name        = "qiita-${var.stage}-ec2"
  description = "security group for EC2"
  vpc_id      = "${aws_vpc.qiita_vpc.id}"
  tags        = { 
    Name = "qiita-${var.stage}-ec2" 
  }
}

resource "aws_security_group_rule" "ec2-ingress" {
  security_group_id        = aws_security_group.ec2.id
  type                     = "ingress"
  source_security_group_id = aws_security_group.alb.id
  from_port                = 0
  to_port                  = 0
  protocol                 = "all"
}

resource "aws_security_group_rule" "ec2-egress_ipv4" {
  security_group_id = aws_security_group.ec2.id
  type              = "egress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}

resource "aws_security_group_rule" "ec2-egress_ipv6" {
  security_group_id = aws_security_group.ec2.id
  type              = "egress"
  ipv6_cidr_blocks  = ["::/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}

resource "aws_security_group" "rds" {
  name        = "qiita-${var.stage}-rds"
  description = "security group for RDS"
  vpc_id      = "${aws_vpc.qiita_vpc.id}"
  tags        = { 
    Name = "qiita-${var.stage}-rds" 
  }
}

resource "aws_security_group_rule" "rds-ingress" {
  security_group_id        = aws_security_group.rds.id
  type                     = "ingress"
  source_security_group_id = aws_security_group.ec2.id
  from_port                = 3306
  to_port                  = 3306
  protocol                 = "tcp"
}

resource "aws_security_group_rule" "rds-egress_ipv4" {
  security_group_id = aws_security_group.rds.id
  type              = "egress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}

resource "aws_security_group_rule" "rds-egress_ipv6" {
  security_group_id = aws_security_group.rds.id
  type              = "egress"
  ipv6_cidr_blocks  = ["::/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "all"
}
```

# プログラムの解説
### ネットワークACL
ネットワークACLとはサブネット単位で入ってくる通信と出て行く通信を制限できるセキュリティレイヤーです。

後ほど説明するセキュリティグループはEC2やRDSのようなインスタンス単位でセキュリティを設定できるのに対し、サブネット単位で設定できる点が異なります。

今回は`aws_default_network_acl`と記載しているので、デフォルトネットワークACLとして対象VPCに属しているサブネット全てに適用されます。

### セキュリティグループ
インスタンス単位でセキュリティを設定できます。
今回はALB, EC2, RDSに対して設定しています。

EC2のインバウンドは、ALBからしか入ってきて欲しくないので、`source_security_group_id`でALBのセキュリティグループのidを指定しています。

同じく、RDSはEC2からしか通信されたくないので、`source_security_group_id`にEC2のセキュリティグループのidを指定しています。

以上でネットワーク周りの実装は完了です。
次回からEC2, RDSの実装に移って行きたいと思います。

# 関連記事
tfenvを用いたterraformのインストール方法
https://qiita.com/sasshi_i/items/b5117d51fed800fa6b09

direnvを用いてterraformで複数のAWSアカウントを使い分ける方法
https://qiita.com/sasshi_i/items/609044aa106cdcb43a89