[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Successor to CentOS] AlmaLinux OS server construction/migration service

[Successor to CentOS] AlmaLinux OS server construction/migration service

[For WordPress only] Cloud server “Web Speed”

[For WordPress only] Cloud server “Web Speed”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Reservation system development] EDISONE customization development service

[Reservation system development] EDISONE customization development service

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[Global exclusive service] Beyond's MSP in North America and China

[Global exclusive service] Beyond's MSP in North America and China

[YouTube] Beyond official channel “Biyomaru Channel”

[YouTube] Beyond official channel “Biyomaru Channel”

Terraform でセキュリティグループに複数ルールを追加する方法

 

*つけ麺 繁田 (神戸六甲道)

こんにちは!
株式会社ビヨンド大阪オフィスのラーメン王、ヒデです。
今回が10回目の投稿です。

前回は、Google Cloud Load Balancing(GCLB)のグローバル外部 HTTP(S) ロードバランサで、URL リダイレクト設定をする方法ついて書きました!

最新型と従来型では、URLリダイレクトの設定が違って少し難しいですが、知っていると便利ですので興味ある方は、以下をぜひ見てくださいね!

● Part1:GCPのグローバル外部 HTTP(S) ロードバランサ(従来型)で、URLリダイレクト設定をする方法
● Part2:GCPのグローバル外部 HTTP(S) ロードバランサで、URLリダイレクト設定をする方法

Terraform でセキュリティグループに複数ルールを追加する

普段、セキュリティグループを作成する時は、インバウンドルールを手動で複数作成してますが、Terraform でも複数のインバウンドルールを設定されているセキュリティグループを作成して、インスタンスなどにアタッチさせたいですよね。

この複数ルールを作成する、2パターンのやり方を紹介します。

下記画像のようにするのが最終目標です!
では頑張っていきましょう!

設定方法

まず、一つ目の設定方法は、aws_security_group に ingress(インバウンドルール)を2つ設定する方法です。
こちらは非常にシンプルでとても使いやすいです。

resource "aws_security_group" "test-sg" {
  name        = "test-sg"
  description = "test-sg"

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

2つ目の設定方法は、aws_security_group_rule を設定する方法です。

aws_security_group にはi ngress を記述せずに、aws_security_group_rule に記述する方法になります。この方法では、一つの aws_security_group_ruleリ ソースの中に、1つのルールしか記述することができないので、複数記述する場合は、下記のようにリソース名を違う名前にした aws_security_group_rule リソースを作成して、その中にルールを追加する方法となります。

しかし、うまく使えば便利かもしれませんが、この aws_security_group_rule を使ってルール設定をする場合は、必ず次を見てから設定をしてください!

resource "aws_security_group" test-sg" {
  name        = "test-sg"
  description = "test-sg"

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

resource "aws_security_group_rule" "test-sg-inbound-http" {
  type      = "ingress"
  from_port = 80
  to_port   = 80
  protocol  = "tcp"
  cidr_blocks = [
    "0.0.0.0/0"
  ]

  security_group_id = aws_security_group.test-sg.id
}

resource "aws_security_group_rule" "test-sg-inbound-https" {
  type      = "ingress"
  from_port = 443
  to_port   = 443
  protocol  = "tcp"
  cidr_blocks = [
    "0.0.0.0/0"
  ]

  security_group_id = aws_security_group.test-sg.id
}

aws_security_group と aws_security_group_rule の両方でルールを設定してはいけない


「aws_security_groupでingress を設定したけど

ingress をもう一つ追加したいから aws_security_group_rule で追加しよ!」

こんな感じで思って aws_security_group でingress ルールを設定しているのに、aws_security_group_rule で追加したら
ルールが競合してapply時に作成されたり、消えたりしてバグります.....

「バグるとかそんなわけないでしょう!何言ってんの?」

こんな感じで思った方はいるはず、初めて知った時は僕も完全にそうでしたw
そんな方のために実際に検証したログを残しておきますね!

以下 main.tf で apply します。

resource "aws_security_group" "test-sg" {
  name        = "test-sg"
  description = "test-sg"

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

resource "aws_security_group_rule" "test-sg-inbound-https" {
  type      = "ingress"
  from_port = 443
  to_port   = 443
  protocol  = "tcp"
  cidr_blocks = [
    "0.0.0.0/0"
  ]

  security_group_id = aws_security_group.test-sg.id
}

1回目の apply で、AWS側ではこうなります。
問題なく 80・443ポートのインバウンドルールが作成されています。

しかし2回目に apply すると、main.tf に何も変更を加えていないのにも関わらず、change となりaws_security_group_rule に設定されているものは、削除されるようになってしまいます。

aws_security_group.test-sg: Refreshing state... [id=sg-063e7c33de8e1dc09]
aws_security_group_rule.test-sg-inbound-https: Refreshing state... [id=sgrule-4193634971]
aws_instance.test: Refreshing state... [id=i-07125d27a59e1b8f5]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.test-sg will be updated in-place
  ~ resource "aws_security_group" "test-sg" {
        id                     = "sg-063e7c33de8e1dc09"
      ~ ingress                = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = ""
              - from_port        = 443
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 443
            },
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = ""
              - from_port        = 80
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 80
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = null
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 80
            },
        ]
        name                   = "test-sg"
        tags                   = {}
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

2回目のapply後のAWS画面は以下になります。aws_security_group_rule で設定された部分は消えてますね。。。

公式の aws_security_group リソースの説明にはこのように書かれています。

要するに aws_security_group_rule に設定しても、aws_security_group に設定した内容に上書きされるということですね。知らないまま運用すると、結構怖いことになりますよね...

Terraform は現在、スタンドアロンのセキュリティ グループ ルール リソース (単一のイングレスまたはエグレス ルール) と、インラインで定義されたイングレスおよびエグレス ルールを含むセキュリティ グループ リソースの両方を提供します。

現時点では、インライン ルールを持つセキュリティ グループをセキュリティ グループ ルール リソースと組み合わせて使用することはできません。これを行うと、ルール設定の競合が発生し、ルールが上書きされます。

● 参考:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group

まとめ

今回は Terraform でセキュリティグループに複数ルールを追加する方法について紹介しましたが、いかがでしたでしょうか?

aws_security_group と aws_security_group_rule で複数のルールを定義できますが、同時にルールを設定すると、とんでもないミスを招く恐れがあるので注意が必要です!

どちらを使うかはお任せしますが、特別な理由がない限りは、aws_security_group で複数のルールを設定する方が、管理が楽で競合も起きないと思います。

セキュリティグループを作成する際はぜひ、参考にしてくださいね!

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
5
読み込み中...
5 票, 平均: 1.00 / 15
6,045
X facebook はてなブックマーク pocket
[2024.6.30 CentOS support ended] CentOS server migration solution

[2024.6.30 CentOS support ended] CentOS server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

The person who wrote this article

About the author

Hide@Infrastructure Engineer

It all started with a very interesting interview.
A mid-career employee of the System Solutions Department in Osaka.My
job is to build and operate servers and clouds!
I have the qualifications of LPIC1, AWS SAA, and OCI Architect Associate.

Actually, I love ramen and
have investigated over 100 stores in Osaka (。-∀-) I'm striving to become the Ramen King of Nibi Beyond
!

I'm also on Twitter, so please follow me (´∇`)
Click on the Twitter mark on the right corner! !