【AWS/Terraform】セキュリティグループの管理

# はじめに
AWSでは、ネットワークレベルでのセキュリティを管理するための重要なツールとしてセキュリティグループが提供されています。この記事では、Terraformを使用してセキュリティグループを管理する方法を記載します。

# 環境
Terraform v1.0.0以上
AWSアカウント登録済み
AWS CLIインストール済み

# ディレクトリ構成
```bash
.
├── main.tf
├── network.tf
├── security_group.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── terraform.tfvars
```

# セキュリティグループとは
AWSのセキュリティグループは、インスタンスへのトラフィックフローを制御する仮想ファイアウォールの一種です。セキュリティグループを使用して、特定のIP範囲からのトラフィックを許可したり、特定のポートへの接続を許可したりすることができます。

# Terraformでのセキュリティグループの管理
main.tfやネットワークに関しては以前作成した[記事](https://qiita.com/yokku21/items/33d797ea5c43e895d516)を参照してください。

https://qiita.com/yokku21/items/33d797ea5c43e895d516

今回は、新しくsecurity_group.tfを作成し、ALB,Web,DBそれぞれ記載します。 

```security_group.tf
# ELB セキュリティグループ
resource "aws_security_group" "elb_sg" {
  name        = "elb_sg"
  description = "elb security group"
  vpc_id      = aws_vpc.vpc.id
  tags = {
    Name = "elb_sg"
  }
}
# ELB セキュリティグループルール HTTPS インバウンド
resource "aws_security_group_rule" "elb_in_https" {
  security_group_id = aws_security_group.elb_sg.id
  type              = "ingress"
  protocol          = "tcp"
  from_port         = 443
  to_port           = 443

  cidr_blocks = ["0.0.0.0/0"]
}

# ELB セキュリティグループルール HTTP インバウンド
resource "aws_security_group_rule" "elb_in_http" {
  security_group_id = aws_security_group.elb_sg.id
  type              = "ingress"
  protocol          = "tcp"
  from_port         = 80
  to_port           = 80

  cidr_blocks = ["0.0.0.0/0"]
}

# ELB セキュリティグループルール HTTP アウトバウンド
resource "aws_security_group_rule" "elb_out_http" {
  security_group_id        = aws_security_group.elb_sg.id
  type                     = "egress"
  protocol                 = "tcp"
  from_port                = 80
  to_port                  = 80
  source_security_group_id = aws_security_group.web_sg.id
}

# WEB セキュリティグループ
resource "aws_security_group" "web_sg" {
  name        = "web_sg"
  description = "web security group"
  vpc_id      = aws_vpc.vpc.id
  tags = {
    Name = "web_sg"
  }
}
# Web セキュリティグループ HTTP インバウンド
resource "aws_security_group_rule" "web_in_http" {
  security_group_id        = aws_security_group.web_sg.id
  type                     = "ingress"
  protocol                 = "tcp"
  from_port                = 80
  to_port                  = 80
  source_security_group_id = aws_security_group.elb_sg.id
}

# Web セキュリティグループ HTTP アウトバウンド
resource "aws_security_group_rule" "web_out_mysql" {
  security_group_id        = aws_security_group.web_sg.id
  type                     = "egress"
  protocol                 = "tcp"
  from_port                = 3306
  to_port                  = 3306
  source_security_group_id = aws_security_group.elb_sg.id
}

# DB セキュリティグループ
resource "aws_security_group" "db_sg" {
  name        = "db_sg"
  description = "db_in security group"
  vpc_id      = aws_vpc.vpc.id
  tags = {
    Name = "db_sg"
  }
}

# DB セキュリティグループ DB インバウンド
resource "aws_security_group_rule" "db_in_mysql" {
  security_group_id        = aws_security_group.db_sg.id
  type                     = "ingress"
  protocol                 = "tcp"
  from_port                = 3306
  to_port                  = 3306
  source_security_group_id = aws_security_group.web_sg.id
}

# 開発 セキュリティグループ
resource "aws_security_group" "dev_sg" {
  name        = "dev_sg"
  description = "dev security group"
  vpc_id      = aws_vpc.vpc.id
  tags = {
    Name = "dev_sg"
  }
}

resource "aws_security_group_rule" "dev_in_http" {
  security_group_id = aws_security_group.dev_sg.id
  type              = "ingress"
  protocol          = "tcp"
  from_port         =  80
  to_port           = 80

  cidr_blocks = ["0.0.0.0/0"]
}

resource "aws_security_group_rule" "dev_in_https" {
  security_group_id = aws_security_group.dev_sg.id
  type              = "ingress"
  protocol          = "tcp"
  from_port         =  443
  to_port           = 443

  cidr_blocks = ["0.0.0.0/0"]
}

resource "aws_security_group_rule" "dev_in_ssh" {
  security_group_id = aws_security_group.dev_sg.id
  type = "ingress"
  protocol = "tcp"
  from_port = 22
  to_port = 22

  cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "dev_out" {
  security_group_id = aws_security_group.dev_sg.id
  type              = "egress"
  protocol          = "-1"
  from_port         =  0
  to_port           = 0

  cidr_blocks = ["0.0.0.0/0"]
}
```

# セキュリティグループの適用
Terraformを使ってセキュリティグループを作成します。terraform applyコマンドを使用すると、Terraformはmain.tf内で定義したリソースを作成します。詳細なプランを見るにはterraform planコマンドを実行します。

```bash
terraform apply
```