チュートリアルのセクション
Tutorial-1. AWSリソースを作成する(初級編)
Tutorial-2. Local Valuesとリソース参照の活用
Tutorial-3. countを使って複数のリソースを一気に作る ←本記事
Tutorial-4. TerraformでAWSリソースを作成する(中級編)
Tutorial-5. for_eachを使ってよりフレキシブルな繰り返し処理を実現する
Tutorial-6. moduleを使ってresourceを共通化する
Tutorial-7. TerraformでAWSリソースを作成する(上級編)
Extra-1. Secret情報を暗号化してGitにアップする
Extra-2. tfstateファイルに外部のストレージを利用する
Extra-3. 他のTerraformで管理しているリソースを参照する
はじめに
ここでは、「AWSで学ぶTerraform実践②〜Local Valuesとリソース参照の活用」で作成したtfファイルを改良して、より利便性を高めるための方法をまとめます。
本セクションのゴール
- countを使って繰り返し処理を実現する
前提条件
「AWSで学ぶTerraform実践②〜Local Valuesとリソース参照の活用」が完了していること
Countについて
countリソースのパラメーターを使用することで、tfファイルの構成を簡素化し、数値をインクリメントするだけでリソースをスケーリングすることができるようになります。言い換えると、同じ種別のリソース時はひとつのresourceで一気に複数のリソースを作成できるということです。
...と言われてもピンと来づらいかと思うので、実際の例をもとに考えてみましょう。
Countを使わない場合の記述方法
例えばひとつのVPC内に3つのSubnetをそれぞれのAZに作成したい場合、これまで学んだ内容をもとに考えると、tfファイルは以下のような記述になります。
resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.vpc.id
cidr_block = local.subnet.subnet1.cidr_block
availability_zone = local.subnet.subnet1.availability_zone
tags = local.subnet.subnet1.tags
}
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.vpc.id
cidr_block = local.subnet.subnet2.cidr_block
availability_zone = local.subnet.subnet2.availability_zone
tags = local.subnet.subnet2.tags
}
resource "aws_subnet" "subnet3" {
vpc_id = aws_vpc.vpc.id
cidr_block = local.subnet.subnet3.cidr_block
availability_zone = local.subnet.subnet3.availability_zone
tags = local.subnet.subnet3.tags
}
合わせて、local.tfも以下のような記述になります。
locals {
owner = "tutorial"
vpc = {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "${local.owner}-vpc"
}
}
subnet = {
subnet1 = {
cidr_block = "192.168.1.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "${local.owner}-public-subnet-1"
}
}
subnet2 = {
cidr_block = "192.168.2.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "${local.owner}-public-subnet-2"
}
}
subnet3 = {
cidr_block = "192.168.3.0/24"
availability_zone = "ap-northeast-1d"
tags = {
Name = "${local.owner}-public-subnet-3"
}
}
}
}
このように、これまでの書き方だとtfファイルにいくつもResourceを書かないといけなくなります。
そうなると、後からSubnetを追加したいときもsubnet.tfとlocal.tfの両方を書き換えないといけないので大変です。
Countを使った場合の記述方法
こういった 同じコンポーネントを複数作成したい場合 、countを使うことでResourceの簡略化が可能です。
実際にSubnetの作成にてcountを使ってみましょう。
subnet_count.tf
まず先にコードを見てみます。
resource aws_subnet subnet {
vpc_id = aws_vpc.vpc.id
count = length(local.subnet)
cidr_block = values(local.subnet)[count.index].cidr_block
availability_zone = values(local.subnet)[count.index].availability_zone
tags = values(local.subnet)[count.index].tags
}
順を追って説明します。
count
(繰り返し処理の回数)は length
という関数によって local.subnet
オブジェクトの要素数(ここではsubnet1/subnet2/subnet3なので要素数は 3
)を取得し指定しています。
そのため、このresourceは3回繰り返しSubnetの作成処理を行います。
しかしこの count
を指定しただけでは、全く同じResourceが3つ作られるだけになってしまいます。
そこできちんと local.tf
で記述したように、一つ目のSubnetは local.subnet.subnet1
の値を参照し、二つ目のSubnetは local.subnet.subnet2
の値を参照するように記述する必要があります。
その記述方法が cidr_block
にあるようなvalues(local.subnet)[count.index]
というコードになります。
-
values:マップを取得し、そのマップ内の要素の値を含むリストを取得します。
- 実際にvalues(local.subnet)の値を取得すると、以下のような形になります。
values_subnet = [
{
availability_zone = "ap-northeast-1a"
cidr_block = "192.168.1.0/24"
tags = {
Name = "tutorial-public-subnet-1"
}
},
{
availability_zone = "ap-northeast-1c"
cidr_block = "192.168.2.0/24"
tags = {
Name = "tutorial-public-subnet-2"
}
},
{
availability_zone = "ap-northeast-1d"
cidr_block = "192.168.3.0/24"
tags = {
Name = "tutorial-public-subnet-3"
}
},
]
-
count.index
:count
数を表します。一回目の処理ではこの値が0
、二回目の処理は1
というようになります。
以上より、 count
の1回目の処理における values(local.subnet)[count.index].cidr_block
は local.subnet[0].cidr_block
を指すことになります。(subnet[0]=local.subnet.subnet1内の要素
)
ちなみに、local.tf
はこのままでOKです。
実際にデプロイしてみる
百聞は一見にしかず、実際に terraform apply
して挙動を確認してみましょう。
ソースコードをgitにあげていますので、cloneしてきます。
git clone https://github.com/skitamura7446/terraform-tutorial.git
cd terraform-tutorial/tutorial-3
次に認証情報を修正します。
provider aws {
access_key = "XXXXXXXXXXXXXXXXXXXXXXXXX" ←自分のアカウントに修正
secret_key = "YYYYYYYYYYYYYYYYYYYYYYYYY" ←自分のアカウントに修正
region = "ap-northeast-1"
}
ディレクトリ構成は以下の通りです。今回はVPCとSubnetだけ作成する簡単な構成になります。
.
├── local.tf
├── provider.tf
├── subnet.tf
├── versions.tf
└── vpc.tf
では terraform plan
でデプロイされるリソースを確認してみましょう。
terraform init
terraform plan
---omit---
Terraform will perform the following actions:
# aws_subnet.subnet[0] will be created
+ resource "aws_subnet" "subnet" {
+ arn = (known after apply)
---omit---
# aws_subnet.subnet[1] will be created
+ resource "aws_subnet" "subnet" {
+ arn = (known after apply)
---omit---
# aws_subnet.subnet[2] will be created
+ resource "aws_subnet" "subnet" {
+ arn = (known after apply)
---omit---
# aws_vpc.vpc will be created
+ resource "aws_vpc" "vpc" {
+ arn = (known after apply)
---omit---
Plan: 4 to add, 0 to change, 0 to destroy.
見てもらうとわかるように、 count
を使うと作成されるリソースは aws_subnet.subnet[0]
のように配列として管理されます。
ではこれをデプロイしてみます。
terraform apply
Resource複数記述とCount利用時の違い
先述したとおり、count
を利用すると該当のresourceを 配列(リスト) として作成します。
そのため、もし count
を利用して作成したリソースを参照したい場合は<resource種別>.<resource名>[配列番号].<参照パラメータ>
というように記述する形になります。
例 : aws_subnet.subnet[0].cidr_block
では本当に上記の記述で参照できるか、 Output
を使って実際に確認してみましょう。
Output
Output
とは、terraform apply
によって作成されるリソースのパラメータ情報をコンソール上に出力したい時に利用されます。例えば、作成したEC2インスタンスのIPアドレスをコンソールに表示させることで、わざわざAWSのWebコンソールを開いてIPアドレスを確認しなくても、SSHアクセスができるようになります。
Output
は他にも使い方がありますが、ここでは割愛します。
今回はこの Output
を使って、 aws_subnet.subnet[0].cidr_block
の値を取得してみましょう。
以下のようなtfファイルを作成して、 terraform apply
してみます。
values
を見ると、count
に対応するよう aws_subnet.subnet[0].cidr_block
という形で参照しているのがわかります。
output "subnet1_cidr" {
description = "values of subnet1 CIDR"
value = aws_subnet.subnet[0].cidr_block
}
terraform apply
すると以下のように、subent1のCIDRが表示されます。
---omit---
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
subnet1_cidr = "192.168.1.0/24"
環境のクリーンアップ
最後にこのセクションで作成した一連のリソースを削除します。
terraform plan -destroy
terraform destroy
おわりに
今回は count
を使ったリソースの繰り返し作成処理を学びました。
次のセクションでは、これまで学んだ内容をもとにTutorial-1よりも少し複雑なAWS環境のデプロイに挑戦します。