LoginSignup
14

More than 5 years have passed since last update.

Terraformでcountをifのように使う

Posted at

はじめに

Terraformでインフラ構成管理をしていると同じtfファイルを使いながらも、特定の環境だけに作りたいリソースが出てくることがあります。

例えば開発環境には社内からのアクセスのみ許可する、といった具合にです。

Terraformにはifのような条件分岐がないものの、countを使うことで上記のことを実現できます。

ベースとなるtfファイル

以下の3つのtfファイルをベースにして説明します。なお利用したTerraformのバージョンはv0.8.4です。

provider.tf
provider "aws" {}
variables.tf
variable "is_dev" {
  default = "0"
}
vm.tf
data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }
  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["099720109477"]
}

resource "aws_security_group" "test-sg-for-all" {
  name = "test-sg-for-all"
  vpc_id = "vpc-xxxxxxxx"
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = [
      "xxx.xxx.xxx.xxx/32"
    ]
  }
  tags {
    Name = "test-sg-for-all"
  }
}

resource "aws_instance" "test-instance" {
  ami = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"
  subnet_id = "subnet-xxxxxxxx"
  security_groups = ["${aws_security_group.test-sg-for-all.id}"]
  tags {
    Name = "test-instance"
  }
}

variables.tfに定義したis_dev変数は、開発環境のときは1で、それ以外のときは0が指定されているものとします。

開発環境のみに作成するリソースを作る

is_dev変数をcountに指定(count = "${var.is_dev}")することで、開発環境のみに作成するリソースを作ることができます。

sample
resource "aws_security_group" "test-sg-for-dev" {
  count = "${var.is_dev}"
  name = "test-sg-for-dev"
  vpc_id = "vpc-xxxxxxxx"
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = [
      "xxx.xxx.xxx.xxx/32"
    ]
  }
}

開発環境のみに作成するリソースと通常のリソースを混ぜて他のリソースで使う

上記で作成した開発環境用のtest-sg-for-devと全環境で作成されるtest-sg-for-allを使ったEC2インスタンスを作成するサンプルが以下になります。

sample
resource "aws_instance" "test-instance" {
  ami = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"
  subnet_id = "subnet-xxxxxxxx"
  security_groups = ["${
    compact(
      concat(
        aws_security_group.test-sg-for-dev.*.id,
        list(aws_security_group.test-sg-for-all.id)
      )
    )
  }"]
  tags {
    Name = "test-instance"
  }
}

ポイントは以下の点です。

  • countを使って作成したリソースをaws_security_group.test-sg-for-dev.*.idのようにListで取得する。
  • 全環境用のリソースはlist()を使い、Listにする。
  • それら2つのListをconcatを使い結合する。
  • is_dev=0のときaws_security_group.test-sg-for-dev.*.idが空文字になるのをcompactで取り除く。

まとめ

Terraformのcountを使ってifのような条件分岐を実装することができました。

TerraformのInterpolation SyntaxにはListを扱う様々なSyntaxが用意されているので、これらを利用してある程度は条件分岐を作ることができます。

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
14