📝

【入門#5】Terraformでセキュリティグループを作ろう

に公開
1

今回の目標

Terraformを使って、EC2とALB用のセキュリティグループを作ります。
今回作成するセキュリティグループルール
ALB用:全てからの443/80を許可
EC2用:ALBからの443/80を許可

◯今回のシステム構成図の全体像

関連記事:https://zenn.dev/alt_tanuki/articles/7c1f97da33496b

実際にかいてみましょう!

1. セキュリティグループを作成する

セキュリティグループはプロジェクトによって数や記載が多くなるため、ファイルはsecurity_groups.tfに切り分けます。
※networkや対象のリソース近くに書くでもいいみたいです。

まずはALB用のセキュリティグループを作成していきます!
security_groups.tfを作成し、下記を記述します。

# SecurityGroup(ALB)
resource "aws_security_group" "cask_tokyo_ec2_sg_alb" {
  name        = "cask-tokyo-ec2-sg-alb"
  description = "For ALB"
  vpc_id      = aws_vpc.cask_tokyo_ec2_vpc.id

  tags = {
    Name = "cask-tokyo-ec2-sg-alb"
  }
}

resource "aws_vpc_security_group_ingress_rule" "cask_tokyo_ec2_sg_alb_http" {
  description       = "From ALL 80"
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "tcp"
  from_port         = 80
  to_port           = 80
}

resource "aws_vpc_security_group_ingress_rule" "cask_tokyo_ec2_sg_alb_https" {
  description       = "From ALL 443"
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "tcp"
  from_port         = 443
  to_port           = 443
}

resource "aws_vpc_security_group_egress_rule" "cask_tokyo_ec2_sg_alb_ipv4" {
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "-1" # all ports
}

resource "aws_vpc_security_group_egress_rule" "cask_tokyo_ec2_sg_alb_ipv6" {
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
  cidr_ipv6         = "::/0"
  ip_protocol       = "-1" # all ports
}

上記でterraform applyを実行するとちゃんとAWSに反映されていますね!

EC2側も追記していきます!
EC2のセキュリティグループはALBからの通信のみ許可するようにインバウンドルールのソースにALBセキュリティグループのIDを入れています。

# SecurityGroup(EC2)
resource "aws_security_group" "cask_tokyo_ec2_sg_ec2" {
  name        = "cask-tokyo-ec2-sg-ec2"
  description = "For EC2"
  vpc_id      = aws_vpc.cask_tokyo_ec2_vpc.id

  tags = {
    Name = "cask-tokyo-ec2-sg-ec2"
  }
}

# インバウンドルール(ingress)
resource "aws_vpc_security_group_ingress_rule" "cask_tokyo_ec2_sg_ec2_http" {
  description       = "From ALB 80"
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_ec2.id
  ip_protocol       = "tcp"
  from_port         = 80
  to_port           = 80
  referenced_security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
}

resource "aws_vpc_security_group_ingress_rule" "cask_tokyo_ec2_sg_ec2_https" {
  description       = "From ALB 443"
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_ec2.id
  ip_protocol       = "tcp"
  from_port         = 443
  to_port           = 443
  referenced_security_group_id = aws_security_group.cask_tokyo_ec2_sg_alb.id
}

# アウトバウンドルール(ingress)
resource "aws_vpc_security_group_egress_rule" "cask_tokyo_ec2_sg_ec2_ipv4" {
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_ec2.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "-1" # all ports
}

resource "aws_vpc_security_group_egress_rule" "cask_tokyo_ec2_sg_ec2_ipv6" {
  security_group_id = aws_security_group.cask_tokyo_ec2_sg_ec2.id
  cidr_ipv6         = "::/0"
  ip_protocol       = "-1" # all ports
}

で、実行結果は

おお!早いですね。

2. 見やすいようにリファクタ

インバウンドルールやアウトバウンドルールはセキュリティグループと同列に書いていくと、少し見づらいですね。
探してみると、セキュリティグループ内の属性としてインバウンド(ingress)/アウトバウンド(egerss)として書くことができるようです。

下記のようにリファクタしてみました。
実行結果はほぼ変化ないですが、だいぶ見やすくなりましたね!!

# SecurityGroup(ALB)
resource "aws_security_group" "cask_tokyo_ec2_sg_alb" {
  name        = "cask-tokyo-ec2-sg-alb"
  description = "For ALB"
  vpc_id      = aws_vpc.cask_tokyo_ec2_vpc.id

  tags = {
    Name = "cask-tokyo-ec2-sg-ec2"
  }

  ingress {
    description       = "From ALL 80"
    protocol          = "tcp"
    from_port         = 80
    to_port           = 80
    cidr_blocks       = ["0.0.0.0/0"]
  }

  ingress {
    description       = "From ALL 443"
    protocol          = "tcp"
    from_port         = 443
    to_port           = 443
    cidr_blocks       = ["0.0.0.0/0"]
  }

  egress {
    description       = "Allow all IPv4"
    protocol          = "-1"
    from_port         = 0
    to_port           = 0
    cidr_blocks       = ["0.0.0.0/0"]
  }

  egress {
    description       = "Allow all IPv6"
    protocol          = "-1"
    from_port         = 0
    to_port           = 0
    ipv6_cidr_blocks = ["::/0"]
  }
}

# SecurityGroup(EC2)
resource "aws_security_group" "cask_tokyo_ec2_sg_ec2" {
  name        = "cask-tokyo-ec2-sg-ec2"
  description = "For EC2"
  vpc_id      = aws_vpc.cask_tokyo_ec2_vpc.id

  tags = {
    Name = "cask-tokyo-ec2-sg-ec2"
  }

  ingress {
    description       = "From ALB 80"
    protocol          = "tcp"
    from_port         = 80
    to_port           = 80
    security_groups   = [aws_security_group.cask_tokyo_ec2_sg_alb.id]
  }

  ingress {
    description       = "From ALB 443"
    protocol          = "tcp"
    from_port         = 443
    to_port           = 443
    security_groups   = [aws_security_group.cask_tokyo_ec2_sg_alb.id]
  }

  egress {
    description       = "Allow all IPv4"
    protocol          = "-1"
    from_port         = 0
    to_port           = 0
    cidr_blocks       = ["0.0.0.0/0"]
  }

  egress {
    description       = "Allow all IPv6"
    protocol          = "-1"
    from_port         = 0
    to_port           = 0
    ipv6_cidr_blocks = ["::/0"]
  }
}

以上!
Terraformでのセキュリティグループ作成でした。

下記の記事を目次として、続きをどんどん構築を行っていきますので今回作成したセキュリティグループの紐づけ方などが気になる方はぜひ見に来てください!

https://zenn.dev/alt_tanuki/articles/7c1f97da33496b

Discussion