3
0

More than 1 year has passed since last update.

AWSで学ぶTerraform実践③〜countを使って複数のリソースを一気に作る

Last updated at Posted at 2023-04-09

チュートリアルのセクション

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ファイルは以下のような記述になります。

subnet.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も以下のような記述になります。

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

まず先にコードを見てみます。

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.indexcount 数を表します。一回目の処理ではこの値が0、二回目の処理は1 というようになります。

以上より、 count の1回目の処理における values(local.subnet)[count.index].cidr_blocklocal.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.tf
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

すると無事Subnetが3つ作成されました。
ScreenShot 63.png

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.tf
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環境のデプロイに挑戦します。

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