9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Terraformとループ

Last updated at Posted at 2021-08-16

hokanでインターン中のかわひとです。

terraformに入門して1週間経ったので、学んだことを記事にしてみました。

ちなみにQiita初記事です!

複数のEC2を一括で立ち上げてみる

for_eachを使う

main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "ec2" {
    source = "./ec2"
    arguments = {
        "example1" = {
            instance_type = "t2.micro"
            ami = "ami-09ebacdc178ae23b7"
        },
        "example2" = {
            instance_type = "t3.nano"
            ami = "ami-0578730a012dc2185"
        },
        "example3" = {
            instance_type = "t2.nano"
            ami = "ami-0df99b3a8349462c6"
        }
    }
}

output "hello" {
  value = module.ec2
}
ec2/ec2.tf
variable "arguments" {
  type = map(map(string))
}

resource "aws_instance" "ec2" {
    for_each = var.arguments
    ami = each.value.ami
    instance_type = each.value.instance_type
    tags = {
        Name = each.key
    }
}

resource "aws_eip" "eip" {
    for_each = aws_instance.ec2
    instance = each.value.id
}

output "ec2_ids" {
    value = { for k, v in aws_instance.ec2 : k => v.id }
}

for_eachはTerraform 0.13から追加された記法です。

公式によると

The for_each meta-argument accepts a map or a set of strings

とありますから、list(map(string))とかループしようとすると怒られます。

また作成された各EC2インスタンスをループすることもできます。

上記のコードでは、各インスタンスをループして、Elastic IP アドレスを登録しています。

各EC2インスタンスへの参照は、aws_instance.ec2[key]です。keyは上記の例でいうと、"example1"や"example2"になります。

# アウトプット
sample_output = {
  "example1" = "i-060e0264a993b95d2"
  "example2" = "i-025aa2d522d80c951"
  "example3" = "i-0c7a2dd83f5f0499e"
}

アウトプット部分で使っているforの記法は、公式サイトを参考にしてください。

countを使う

terraformでは、count を使えば単純に数を増やせます。

resource "aws_instance" "ec2" {
    ami = "ami-09ebacdc178ae23b7"
    instance_type = "t2.micro"
    count = 10
}

同じ性能のインスタンスが10個立ち上がります。

インスタンスによって値を変えたい場合は、count.indexを利用します。

main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "ec2" {
    source = "./ec2"
    arguments = [
        {
            name = "example1"
            instance_type = "t2.micro"
            ami = "ami-09ebacdc178ae23b7"
        },
        {
            name = "example2"
            instance_type = "t3.nano"
            ami = "ami-0578730a012dc2185"
        },
        {
            name = "example3"
            instance_type = "t2.nano"
            ami = "ami-0df99b3a8349462c6"
        }
    ]
}

output "sample_output" {
  value = module.ec2.ec2_id
}

ec2/ec2.tf
variable "arguments" {
  type = list(map(string))
}

resource "aws_instance" "ec2" {
    count = length(var.arguments)
    ami = var.arguments[count.index].ami
    instance_type = var.arguments[count.index].instance_type
    tags = {
        Name = var.arguments[count.index].name
    }
}

resource "aws_eip" "eip" {
    count = length(var.arguments)
    instance = aws_instance.ec2[count.index].id
}

output "ec2_id" {
    value = aws_instance.ec2.*.id
    # * = 1, 2, 3
}

count = length(var.arguments)とすることで、リストの長さ分だけEC2インスタンスを作成します。またcount.indexを使うことで、リストの各要素を取り出しています。

for_eachではmapをループしましたが、countの構文ではリストをループする感じです。

またoutputの中では、*という記号でindexを使えるっぽいです。

# アウトプット
sample_output = [
  "i-0a45fc109254eb6ea",
  "i-0dd457447e07d00ee",
  "i-00b310944d415a592",
]

セキュリティグループのルール

ネストされたブロック内でループするには、dynamicブロックを使う必要があります。

普通にfor_eachを使おうとするとエラーがでるので注意が必要です。

variable "ingressrules" {
  type = list(number)
  default = [80, 443, 22, 25]
}

resource "aws_security_group" "sample" {
  dynamic "ingress" {
    for_each = var.ingressrules
    content {
      from_port = ingress.value
      to_port = ingress.value
      protocol = "TCP"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

とくにセキュリティグループのインバウンド/アウトバウンドルールは、単純なループになりがちなので、この記法が活躍すると思います。

for_eachの各要素にアクセスするには、each.value ではなく、ブロック名.value とする点に注意が必要です。

なお iterator を指定すると、iterator名.value とできます。

↓dynamic ブロックの使い方はこちら。

9
3
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
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?