👻

Terraformでセキュリティグループのルールをモジュール外に切り出すメリット

2025/02/14に公開2

Terraformでセキュリティグループを定義する際、モジュール内にルールをインラインで書くと、モジュールを呼び出す側ではルールを変更できなくなります。モジュール利用者が柔軟にルールを追加・変更したいケースでは、インラインから「モジュールの外」に切り出す方法が有効です。

インラインで指定した場合の問題点

モジュール内で直にセキュリティグループとそのルールを定義すると、モジュールに含まれるリソースの挙動が固定化されます。たとえば次のようにインラインでルールを指定した場合、モジュールを呼び出す側ではルールを後から変更することができません。

// modules/hoge/main.tf
resource "aws_security_group" "main" {
  name   = "セキュリティグループ"
  vpc_id = var.vpc_id

  ingress {
    protocol        = var.protocol
    from_port       = var.port
    to_port         = var.port
    security_groups = var.source_security_group_ids
  }

  egress {
    protocol    = var.protocol
    from_port   = var.port
    to_port     = var.port
    cidr_blocks = var.cidr_blocks
  }
}

ルールを外に出すアプローチ

一方、モジュール側ではセキュリティグループを定義するだけに留め、ルール部分はモジュールを利用する側で別途定義するように変更することで、モジュール利用者が自由にルールを設定できるようになります。例として、モジュール側(以下「modules/hoge」)を次のようにシンプルに作成します。

// modules/hoge/main.tf
resource "aws_security_group" "main" {
  name   = "データベースのセキュリティグループ"
  vpc_id = var.vpc_id
}

output "security_group_id" {
  value = aws_security_group.main.id
}

そして、モジュールを利用する側(例: main.tf)では、モジュールから受け取ったセキュリティグループIDを使い、aws_security_group_ruleでルールを自由に定義できるようにします。

// main.tf
module "hoge" {
  source = "./modules/hoge"
  vpc_id = var.vpc_id
}

resource "aws_security_group_rule" "ingress" {
  security_group_id = module.hoge.security_group_id
  type              = "ingress"
  protocol          = "tcp"
  from_port         = 3306
  to_port           = 3306
  cidr_blocks = ["0.0.0.0/0"]
}

おわりに

セキュリティグループのルールがモジュール内で決まっているだけで、モジュールの柔軟性や疎結合が損なわれるなあと思っていたら、ルールを外に出す方法があることを知りました。モジュール内にいれることを責任が明確になるメリットもあるので、適切に使い分けると良いのかなと思います

株式会社ソニックムーブ

Discussion

m.okamuram.okamura

aws_security_group_rule自体もモジュールに入れたりします。
こうすることで、

  • メリット
    • セキュリティグループとルールの関連を定義できる
  • デメリット
    • パラメータが肥大化する可能性がある

などが得られるのでこちらも適宜検討してみるといいかもと思います。