workspaceを使って複数リージョンのインフラ環境をサクッと作って管理してみる。
マルチリージョン構成ので同じ構成のVPCを展開する時に便利。
workspaceについてはこの記事を参考に
今回のversion
$ terraform --version
Terraform v1.0.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.42.0
Your version of Terraform is out of date! The latest version
is 1.0.6. You can update by downloading from https://www.terraform.io/downloads.html
やっていきましょう。
workspaceはawsのregion名で作成。
default
* ap-northeast-1
us-east-1
us-west-2
下記のように変数を作成。
default配下はworkspace名と同一のものにする。
variable “region” {
description = “AWS region.”
type = map(string)
default = {
“default.region” = “ap-northeast-1"
“ap-northeast-1.region” = “ap-northeast-1"
“us-west-2.region” = “us-west-2"
“us-east-1.region” = “us-east-1"
}
}
workspace名を変数とし、以下のように呼び出し。
client.tf
provider “aws” {
region = lookup(var.region, “${terraform.workspace}.region”)
access_key = “********”
secret_key = “********”
}
${terraform.workspace} でworkspace名を呼びだして vpc と文字列結合している。
workspaceが東京リージョンの場合、出力される文字列は ap-northeast-1.region となり、Valueの ap-northeast-1 が呼び出される。
・変数リストの取り扱い
下記の様な記述でリストを変数に格納する。
subnetはご自由にどうぞ。
variable “public_subnet_cidr” {
description = “public subnet cidr block”
default = {
“default.public_cidr” = [“10.184.0.0/19", “10.184.32.0/19”, “10.184.64.0/19", “10.184.192.0/22”, “10.184.196.0/22", “10.184.200.0/22”]
“ap-northeast-1.public_cidr” = [“10.184.0.0/19”, “10.184.32.0/19", “10.184.64.0/19”, “10.184.192.0/22", “10.184.196.0/22”, “10.184.200.0/22"]
“us-west-2.public_cidr” = [“10.182.0.0/19", “10.182.32.0/19”, “10.182.64.0/19", “10.182.192.0/22”, “10.182.196.0/22", “10.182.200.0/22”]
“us-east-1.public_cidr” = [“10.180.0.0/19”, “10.180.32.0/19", “10.180.64.0/19”, “10.180.192.0/22", “10.180.196.0/22”, “10.180.200.0/22"]
}
}
呼び出し方は同様
# public subnet
resource “aws_subnet” “public” {
count = 6
vpc_id = aws_vpc.main.id
availability_zone = element(lookup(var.az, “${terraform.workspace}.az”), count.index)
cidr_block = element(lookup(var.public_subnet_cidr, “${terraform.workspace}.public_cidr”), count.index)
map_public_ip_on_launch = element(var.launch_ip, count.index)
tags = {
Name = element(var.public_tags, count.index)
}
}
lookupで対象リージョンのリストを呼び出し、element関数でsubnetを6つ作成している。
以下、ディレクトリ構造
tree./
./
├── client.tf
├── internet_gateway.tf
├── main.tf
├── nat_gateway.tf
├── route_table.tf
├── routing.tf
├── subnet.tf
├── terraform.tfstate.d
│ ├── ap-northeast-1
│ │ ├── terraform.tfstate
│ │ └── terraform.tfstate.backup
│ ├── us-east-1
│ │ ├── terraform.tfstate
│ │ └── terraform.tfstate.backup
│ └── us-west-2
│ ├── terraform.tfstate
│ └── terraform.tfstate.backup
└──variables.tf
client.tf
provider “aws” {
region = lookup(var.region, “${terraform.workspace}.region”)
access_key = “********”
secret_key = “********”
}
internet_gateway.tf
# Internet Gateway
resource “aws_internet_gateway” “main” {
vpc_id = aws_vpc.main.id
tags = {
Name = lookup(var.vpc_name, “${terraform.workspace}.vpc_name”)
}
main.tf
# VPC
resource “aws_vpc” “main” {
cidr_block = lookup(var.vpc, “${terraform.workspace}.vpc”)
enable_dns_hostnames = true
tags = {
Name = lookup(var.vpc_name, “${terraform.workspace}.vpc_name”)
}
}
nat_gateway.tf
# Elastic IP
resource “aws_eip” “nat_1a” {
vpc = true
tags = {
Name = “natgw”
}
}
# NAT Gateway
resource “aws_nat_gateway” “nat_1a” {
subnet_id = aws_subnet.public[0].id
allocation_id = aws_eip.nat_1a.id
tags = {
Name = lookup(var.vpc_name, “${terraform.workspace}.vpc_name”)
}
}
route_table.tf
# Route table (private)
resource “aws_default_route_table” “private” {
default_route_table_id = aws_vpc.main.default_route_table_id
tags = {
Name = “private”
}
}
# Route Table (public)
resource “aws_route_table” “public” {
vpc_id = aws_vpc.main.id
tags = {
Name = “public”
}
}
routing.tf
# Route (Private)
resource “aws_route” “private_1a” {
destination_cidr_block = “0.0.0.0/0"
route_table_id = aws_vpc.main.default_route_table_id
nat_gateway_id = aws_nat_gateway.nat_1a.id
}
# Route (public)
resource “aws_route” “public” {
destination_cidr_block = “0.0.0.0/0”
route_table_id = aws_route_table.public.id
gateway_id = aws_internet_gateway.main.id
}
# Association
resource “aws_route_table_association” “public” {
count = 6
route_table_id = aws_route_table.public.id
subnet_id = element([aws_subnet.public[0].id, aws_subnet.public[1].id, aws_subnet.public[2].id, aws_subnet.public[3].id, aws_subnet.public[4].id, aws_subnet.public[5].id, ], count.index)
}
subnet.tf
# public subnet
resource “aws_subnet” “public” {
count = 6
vpc_id = aws_vpc.main.id
availability_zone = element(lookup(var.az, “${terraform.workspace}.az”), count.index)
cidr_block = element(lookup(var.public_subnet_cidr, “${terraform.workspace}.public_cidr”), count.index)
map_public_ip_on_launch = element(var.launch_ip, count.index)
tags = {
Name = element(var.public_tags, count.index)
}
}
# private subnet
resource “aws_subnet” “private” {
count = 6
vpc_id = aws_vpc.main.id
availability_zone = element(lookup(var.az, “${terraform.workspace}.az”), count.index)
cidr_block = element(lookup(var.private_subnet_cidr, “${terraform.workspace}.private_cidr”), count.index)
tags = {
Name = element(var.private_tags, count.index)
}
}
variables.tf
variable “region” {
description = “AWS region.”
type = map(string)
default = {
“default.region” = “ap-northeast-1”
“ap-northeast-1.region” = “ap-northeast-1”
“us-west-2.region” = “us-west-2”
“us-east-1.region” = “us-east-1”
}
}
variable “vpc” {
description = “AWS vpc.”
type = map(string)
default = {
“default.vpc” = “10.184.0.0/16”
“ap-northeast-1.vpc” = “10.184.0.0/16”
“us-west-2.vpc” = “10.182.0.0/16”
“us-east-1.vpc” = “10.180.0.0/16”
}
}
variable “vpc_name” {
description = “vpc name.”
type = map(string)
default = {
“default.vpc_name” = “hoge JP”
“ap-northeast-1.vpc_name” = “hoge JP”
“us-west-2.vpc_name” = “hoge OR”
“us-east-1.vpc_name” = “hoge VA”
}
}
variable “az” {
description = “availability zone.”
default = {
“default.az” = [“ap-northeast-1a”, “ap-northeast-1c”, “ap-northeast-1d”, “ap-northeast-1a”, “ap-northeast-1c”, “ap-northeast-1d”]
“ap-northeast-1.az” = [“ap-northeast-1a”, “ap-northeast-1c”, “ap-northeast-1d”, “ap-northeast-1a”, “ap-northeast-1c”, “ap-northeast-1d”]
“us-west-2.az” = [“us-west-2a”, “us-west-2b”, “us-west-2c”, “us-west-2a”, “us-west-2b”, “us-west-2c”]
“us-east-1.az” = [“us-east-1a”, “us-east-1b”, “us-east-1c”, “us-east-1a”, “us-east-1b”, “us-east-1c”]
}
}
variable “public_subnet_cidr” {
description = “public subnet cidr block”
default = {
“default.public_cidr” = [“10.184.0.0/19”, “10.184.32.0/19", “10.184.64.0/19”, “10.184.192.0/22", “10.184.196.0/22”, “10.184.200.0/22"]
“ap-northeast-1.public_cidr” = [“10.184.0.0/19", “10.184.32.0/19”, “10.184.64.0/19", “10.184.192.0/22”, “10.184.196.0/22", “10.184.200.0/22”]
“us-west-2.public_cidr” = [“10.182.0.0/19”, “10.182.32.0/19", “10.182.64.0/19”, “10.182.192.0/22", “10.182.196.0/22”, “10.182.200.0/22"]
“us-east-1.public_cidr” = [“10.180.0.0/19", “10.180.32.0/19”, “10.180.64.0/19", “10.180.192.0/22”, “10.180.196.0/22", “10.180.200.0/22”]
}
}
variable “private_subnet_cidr” {
description = “private subnet cidr block”
default = {
“default.private_cidr” = [“10.184.96.0/19”, “10.184.128.0/19", “10.184.160.0/19”, “10.184.204.0/22", “10.184.208.0/22”, “10.184.212.0/22"]
“ap-northeast-1.private_cidr” = [“10.184.96.0/19", “10.184.128.0/19”, “10.184.160.0/19", “10.184.204.0/22”, “10.184.208.0/22", “10.184.212.0/22”]
“us-west-2.private_cidr” = [“10.182.96.0/19”, “10.182.128.0/19", “10.182.160.0/19”, “10.182.204.0/22", “10.182.208.0/22”, “10.182.212.0/22"]
“us-east-1.private_cidr” = [“10.180.96.0/19", “10.180.128.0/19”, “10.180.160.0/19", “10.180.204.0/22”, “10.180.208.0/22", “10.180.212.0/22”]
}
}
variable “launch_ip” {
default = [“true”, “true”, “true”, “false”, “false”, “false”]
}
variable “public_tags” {
default = [“public1", “public2”, “public3", “elb_public1”, “elb_public2", “elb_public3”]
}
variable “private_tags” {
default = [“private1”, “private2", “private3”, “elb_private1", “elb_private2”, “elb_private3"]
}
作成時は少しややこしく感じますが、各リソースの依存関係や変数を理解して作ってしまえば後々使い回しができるのでなんだかんだ便利ですね。