terraformでsecurity groupをmodule化するときに気をつけること

IPアドレスを定義した共通のsecurity groupを作りたい

あるプロジェクトで外部のIPアドレスなどをまとめたものをsecurity groupとしてmodule化している。このアイディア自体はいいんだけど、環境ごとにこれを利用しようとした場合に失敗する。

例えば、こんな感じでmodulesに外部IPを書いたようなsecurity_groupをつくる。

terraform
├── development
│   └── main.tf
├── staging
│   └── main.tf
├── production
│   └── main.tf
└── modules
    └── external_ips_sg
        ├── security_group.tf
        └── outputs.tf

で、これらを各環境のmain.tfで利用すると、同一のsgを作ろうとするので、security groupの名前を変える必要がある。

module "external_ips_sg" {
  source = "../modules/external_ips_sg"
}

ここで、security groupのnameを変数化しておかないと同じ名前のsecurity groupを作ろうとして失敗する。

解決策

当たり前の話だけど、変数でnameを変えられるようにしておく。

└── modules
    └── external_ips_sg
        ├── variables.tf
        ├── security_group.tf
        └── outputs.tf
variable "env" {}
variable "vpc_id" {}
module "external_ips_sg" {
  source = "../modules/external_ips_sg"

  env = "dev"
  vpc_id = "vpc-xxxxxxxx"
}
resource "aws_security_group" "a" {
  name = "external-ips-${var.env}"
  vpc_id = "${var.vpc_id}"

ちなみに、Security GroupのDescriptionはForce new Resourceなのであとから変更できないので、何も設定しない方がいいかも。ちょっと文言変えたいなーってときにもう変更できない。何も設定しなければ、 Mangaed By Terraformのデフォルト文言が設定される。何か名前付けをしたい場合は、TagのNameを使おう。 あと、vpc_idを入れるのを忘れがち。vpc_idはなければ自動的にdefautl vpcが設定されるのでうまくいってしまう。