0
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でAWSの本番以外にALBでIPアドレス制限をかける [★☆☆:初心者向け]

0
Last updated at Posted at 2025-07-26

はじめに

AWS上に構築する開発環境のALBに対して、セキュリティ面から特定のIPアドレスからのみアクセスを許可することにしました。しかし同じTerraformコードを使って本番環境も管理しており、本番はIP制限をかけてはいけないため、環境によって異なる設定を適用する必要がありました。

対象読者

  • Terraformで複数環境を管理している人
  • 開発環境のセキュリティを強化したい人

この記事からわかること

  • Terraformで環境別にセキュリティグループルールを制御する方法
  • 条件分岐を使った柔軟な設定の実装
  • tfvarsファイルを使った環境固有の設定管理

この記事では説明しないこと

  • AWSセキュリティグループの基本概念
  • Terraformの変数の使い方
  • ALB(Application Load Balancer)の設定方法

状況

セキュリティグループのingressルールでCIDRブロックが固定値(0.0.0.0/0)になってて、環境に応じた制御の仕組みはありませんでした。

# 修正前:すべての環境で全IPアドレスを許可
resource "aws_security_group_rule" "alb_ingress_https" {
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]  # 固定値
  security_group_id = aws_security_group.alb.id
}

環境

  • Terraform v1.5.7

方針検討

検討した方法

1. 条件分岐(三項演算子)を使う方法

cidr_blocks = var.environment == "development" ? var.alb_allowed_ips : ["0.0.0.0/0"]
  • メリット: シンプルで読みやすい
  • デメリット: 複雑な条件には向かない

今回の要件には十分なのでこれでいきましょう

2. count/for_eachでリソースを分ける方法

resource "aws_security_group_rule" "alb_ingress_https_dev" {
  count = var.environment == "development" ? 1 : 0
  # 開発環境用の設定
}

resource "aws_security_group_rule" "alb_ingress_https_prod" {
  count = var.environment == "production" ? 1 : 0
  # 本番環境用の設定
}
  • メリット: 環境ごとに完全に異なる設定が可能
  • デメリット: リソースが重複して管理が複雑

メンテしずらいため却下...

解決策

Terraformの条件分岐(三項演算子)を使って、環境変数の値に応じてCIDRブロックを切り替える方法で実装します。

実装手順

1. 変数定義(variables.tf)

まず変数を定義します。設定し忘れた時に色々すり抜けて本番に適用されてもいいように、alb_allowed_ipsのデフォルト値は全IP許可にしています。

variable "environment" {
  description = "Environment name"
  type        = string
}

variable "alb_allowed_ips" {
  description = "Allowed IP addresses for ALB access"
  type        = list(string)
  default     = ["0.0.0.0/0"]  # デフォルトは全IP許可
}

2. セキュリティグループルールの実装

シンプルに三項演算子で環境別に切り替えます。HTTP/HTTPSなど複数のルールがあったので同じロジックを適用しました。

security.tf ※ファイル名は任意

# HTTPアクセス
resource "aws_security_group_rule" "alb_ingress_http" {
  type              = "ingress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  # 環境に応じてCIDRブロックを切り替え
  cidr_blocks       = var.environment == "development" ? var.alb_allowed_ips : ["0.0.0.0/0"]
  security_group_id = aws_security_group.alb.id
}

# HTTPSアクセス
resource "aws_security_group_rule" "alb_ingress_https" {
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = var.environment == "development" ? var.alb_allowed_ips : ["0.0.0.0/0"]
  security_group_id = aws_security_group.alb.id
}

3. 環境別設定ファイル

tfvarsファイルでアクセスを許可するCIDR指定。あとで絶対「このIPなんだっけ?」となるので、コメントで用途を記載推奨です。
例えば開発環境:development.tfvars、本番環境:production.tfvarsとする場合の例↓

development.tfvars ※記載のIPは適当です

environment = "development"

# ALB Access Control
# 特定のIPアドレスのみ許可
alb_allowed_ips = [
  "203.0.113.10/32",    # オフィスIP1
  "203.0.113.20/32",    # オフィスIP2
  "198.51.100.0/24"     # 検証用端末
]

production.tfvars

environment = "production"
# 本番環境では変数を指定しない(デフォルトの0.0.0.0/0が適用される)

4. 適用方法

実際に適用するときはこんな感じです。planで確認してからapplyします。(applyをいきなり実行してもOKです。お好みで)

# 開発環境への適用
terraform plan -var-file=development.tfvars
terraform apply -var-file=development.tfvars

# 本番環境への適用
terraform plan -var-file=production.tfvars
terraform apply -var-file=production.tfvars

ボツ案

途中、localsブロックで環境別の設定をまとめた方が楽かな?と思いました。
実際にやろうとするとmapのキーが存在しないときのエラーハンドリングが面倒だったので、シンプルな三項演算子に落ち着きました。

# イマイチだった方法
locals {
  cidr_blocks = {
    development = var.alb_allowed_ips
    production  = ["0.0.0.0/0"]
  }
}

# 使うとき
cidr_blocks = local.cidr_blocks[var.environment]

ポイント

  1. デフォルト値で事故を防止する: 何より本番に誤った値をapplyするのが怖いので、デフォルトは本番の設定["0.0.0.0/0"]にしておきます
  2. 運用負担を感じたら...: 開発メンバーが増えたりリモートワークしたりで設定するIPが増えると面倒なので、VPN使用などしたほうがよいと思います

ひとこと

Terraform、tfファイルの作成は割と直感的。ドリフトしたときが...

0
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
0
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?