1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Terraform】tfファイル書いてて詰まったところ セキュリティグループ編

1
Last updated at Posted at 2026-02-22

Terraform で VPC + RDS + Lambda あたりの構成を1から書いている。AIに指導役になってもらって、自分でコードを書いては都度レビューしてもらうという進め方。

Security Group まわりで何回も指摘をもらったので、備忘録として残しておく。

型がバラバラで混乱する

Security Group の各フィールドを並べると型がバラバラで最初は戸惑った。

from_port   = 0               → number
protocol    = "-1"            → string
cidr_blocks = ["0.0.0.0/0"]  → list(string)

なぜ -1 は数値じゃなくて文字列なのか、という疑問が湧いたけど、これは Terraform が勝手に決めているわけではなく AWS の API 仕様がそうなっている。型に迷ったら terraform validate を実行すればエラーで教えてくれる。

ingress に = を付けてしまう

# NG
ingress = {
  from_port = 5432
}

# OK
ingress {
  from_port       = 5432
  to_port         = 5432
  protocol        = "tcp"
  security_groups = [aws_security_group.lambda.id]
}

tagsの書き方で勢いのまま、同じ書き方をしてしまった。
指摘を受けて = を外したら通ったけど、なぜ tags には = が付いて ingress には付かないのかが分からなかった。どっちも { } で囲んでいるのに何が違うのか。

そもそも map 型とは

tags の書き方を改めて見るとこうなっている。

tags = {
  Name        = "my-rds-sg"
  Environment = "dev"
}

これは map 型(キーと値のペアの集まり)の値を tags という属性に代入している。Python でいう辞書、JSON でいうオブジェクトに近い。キーも値も自由に決められて、Project = "tiled" とか好きなものを足せる。

ポイントは tags は「1つの値」を受け取っているということ。その値がたまたま { } を使う map 型なだけで、やっていることは vpc_id = "vpc-xxxxx" と同じ「属性への代入」。

ブロックとの違い

一方 ingress はブロック。

ingress {
  from_port       = 5432
  to_port         = 5432
  protocol        = "tcp"
  security_groups = [aws_security_group.lambda.id]
}

ブロックは「この種類の設定を1セット定義する」という構造で、値の代入ではない。中に書けるフィールドは Provider 側で決まっていて、自由にキーを足すことはできない。そして複数書けばルールを複数作れる。

# ingressブロックを2つ書けば、ルールが2つできる
ingress {
  from_port   = 443
  to_port     = 443
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}

ingress {
  from_port       = 5432
  to_port         = 5432
  protocol        = "tcp"
  security_groups = [aws_security_group.lambda.id]
}

見分け方

= が付く   → 属性(値を代入している。map型でも代入は代入)
= が付かない → ブロック(設定の構造を定義している)

見た目が似ているので最初は混乱したけど、代入か、定義かで考えるとすっきりした。

security_groups をリストにしなかった

# NG
security_groups = aws_security_group.lambda.id

# OK
security_groups = [aws_security_group.lambda.id]

security_groupslist(string) 型。1つしか指定しなくても [] で囲む必要がある。cidr_blocks と同じ。

RDS SG の最終形

上の間違いを全部直すとこうなった。

resource "aws_security_group" "rds" {
  name        = "${var.project_name}-rds-sg-${var.environment}"
  description = "RDS PostgreSQL access from Lambda only"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.lambda.id]
  }

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

  tags = {
    Name = "${var.project_name}-rds-sg-${var.environment}"
  }
}

Terraform は型付き言語なので、フィールドの型を間違えると容赦なく怒られる。迷ったら terraform validate で確認するのが一番早い。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?