1
1

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でAWSのセキュリティグループを作成したときにハマったこと

Posted at

セキュリティグループ設定で盛大にハマって時間を食ったので、備忘録としてまとめます。

  • 目的:TerraformでEC2を立ててSSM(Session Manager)で接続し、22番を開けない / 鍵管理をなくす
  • 症状:マネジメントコンソールから SSM接続できない
  • 結論:Security Group のアウトバウンド(Egress)が全拒否になっていて、SSMが必要とする アウトバウンド 443 が塞がっていた

参考ドキュメント

  • Terraform AWS Provider: aws_security_group


何をしたかったか

Terraformでこんな構成を作りました。

  • EC2(アプリ)を起動
  • インバウンドは必要最低限(例:アプリの3000だけ)
  • SSH(22)は開けず、代わりに SSMで接続

SSMで接続できれば、

  • 22を開けない(踏み台不要 / ポートスキャンの面倒が減る)
  • キーペア運用(鍵の配布・失効・漏洩対応)を減らせる

…という期待でした。


起きたこと(症状)

IAMロール(AmazonSSMManagedInstanceCore)は付けているのに、コンソールからSession Managerで接続しようとすると失敗。

原因調査のために結局SSHで接続し、

  • amazon-ssm-agent の存在と起動は確認できた
  • でも EC2内から curl https://example.com が返ってこない

ここで「外向き通信が死んでる=ネットワーク(特にEgress)が怪しい」と判断しました。


SSM(Session Manager)の通信の仕組み

SSMは「クライアント→EC2」に直接つなぎにいく仕組みではありません。

SSHとの違い

  • SSH:クライアント →(インバウンド22)→ EC2
  • SSM:EC2上のSSM AgentがAWS側のSystems Managerへアウトバウンドで通信し続けることで成立

つまり、SSMは “外から入ってくる”のではなく“中から取りに行く(張りにいく)”モデルです。

SSMは「ポーリング+双方向チャンネル」

SSM Agent は概ね以下の動きをします。

  1. 定期的にAWS側へポーリングを送る
    • 「このインスタンスは生きてます」「どのバージョンです」など
  2. セッション開始時は、AWS側(Session Manager)と双方向の通信チャネルを張る
    • 入力(あなたのキーボード)と出力(シェルの結果)をストリーミングするイメージ

このとき必要なのがアウトバウンドのHTTPS(tcp/443)です。


なぜ原因特定に時間がかかったか

普段AWSのSecurity Groupは「アウトバウンド全許可」になっていることが多く、Egressで詰まる発想になりにくいです。

しかし、今回のSGはアウトバウンドルールが空(= 全拒否)になっていました。

結果として、

  • curl https://example.com がタイムアウト / 接続できない
  • dnf update / dnf install も失敗する
  • SSM AgentもAWSへ到達できず、結果としてSSM接続できない

結論(今回の原因)

そもそも公式のドキュメントの読み込みが甘かったです。
以下の部分を読み飛ばしていました。

スクリーンショット 2026-01-02 13.44.38.png
簡単に訳すと、「AWSはデフォルトでアウトバウンドを全許可で作るけど、Terraformはこれを除外しますよ〜。必要なら自分で追加してね」ということらしいです。

Security Groupのアウトバウンド(Egress)が全拒否になっており、SSMに必要なアウトバウンド443が通っていなかった。


何を変更したか

Before(Egressを書いていなかった)

resource "aws_security_group" "allow_myip" {
  name        = "allow_myip"
  description = "allow myip"
  vpc_id      = aws_vpc.main.id

  tags = {
    Name = "allow_myip"
  }
}

resource "aws_vpc_security_group_ingress_rule" "allow_myip_3000" {
  security_group_id = aws_security_group.allow_myip.id
  cidr_ipv4         = local.myip_cidr
  from_port         = 3000
  to_port           = 3000
  ip_protocol       = "tcp"
}

After(アウトバウンド443を明示)

hcl
resource "aws_security_group" "allow_myip" {
  name        = "allow_myip"
  description = "allow myip"
  vpc_id      = aws_vpc.main.id

  # 追加:アウトバウンドHTTPS(443)を許可(SSM / パッケージ取得 / curl など)
  egress {
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "allow_myip"
  }
}

resource "aws_vpc_security_group_ingress_rule" "allow_myip_3000" {
  security_group_id = aws_security_group.allow_myip.id
  cidr_ipv4         = local.myip_cidr
  from_port         = 3000
  to_port           = 3000
  ip_protocol       = "tcp"
}

学び

ドキュメントはしっかり読みましょう(自戒の意味も込めて)

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?