Help us understand the problem. What is going on with this article?

Terraformでゾーン毎にsubnetを作成する(AWS, Alicloud)。

高可用性なサーバー配置

可用性が高いサーバーの配置として、ゾーン毎に立てるのは常套手段と思う。クラウドベンダーの1つのゾーンに障害が発生しても、別のゾーンが生きていればサービスの継続性が保たれる。
その前準備として、ゾーン毎にsubnetを作成する手順をterraformで自動化する。
terraformへは、regionとVPCのCIDRのみを指定し後はよしなにやってくれること、AWSとAlicloudで同じような自動化ができることを確認する。

input/output

input
- region
- VPCのCIDR

output
- VPC
- ゾーン毎のsubnet

つまり、入力のregionにVPCを作成して、そのregionが持つゾーン毎にsubnetを作成する。

クラウド・プロバイダの設定

main_alicloud.tf
# Alicloud Providerの設定
provider "alicloud" {
  access_key = var.alicloud_access_key
  secret_key = var.alicloud_secret_key
  region     = var.alicloud_region
}

access_keyとsecret_keyはvariables.tfで設定するが、このような設定ファイルに残したくない場合は環境変数へ設定する方法もある。
それぞれALICLOUD_ACCESS_KEYALICLOUD_SECRET_KEYへ設定すれば良い。

main_aws.tf
# AWS Providerの設定
provider "aws" {
  region = var.aws_region
}

AWSでは、access_keyとsecret_keyは~/.aws/credentialsに設定してある。

利用できるゾーンを取得する

main_alicloud.tf
# 有効なゾーンを問い合わせ、local.all_zonesで参照する
data "alicloud_zones" "available" {
}
locals {
  all_zones = data.alicloud_zones.available.ids
}

alicloud_zonesでゾーンを問い合わせ、local変数のall_zonesへ設定している。
ちなみにAlicloudのap-northeast-1は、ゾーン数が2つであった。

  • ap-northeast-1a
  • ap-northeast-1b
main_aws.tf
# 有効なゾーンを問い合わせ、local.all_zonesで参照する
data "aws_availability_zones" "available" {
  state = "available"
}
locals {
  all_zones = data.aws_availability_zones.available.names
}

Alicloudとほとんど変わらないコード。
AWSのコードの方がより明確な指示ができる(state = "available")。AlicloudはAsIsで同じように動作するだけかも。。

VPCの作成

main_alicloud.tf
# VPCの作成
resource "alicloud_vpc" "vpc" {
  name       = "${var.base_name}-vpc"
  cidr_block = var.vpc_cidr
}

vpc.PNG

main_aws.tf
# VPCの作成
resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr
  tags = map(
    "Name", "${var.base_name}-vpc",
  )
}

両クラウドでほとんど変わらないコード。VPCのCIDRはvariables.tfで設定する。

subnetの作成

main_alicloud.tf
# vswitch(subnet)の作成
resource "alicloud_vswitch" "vsw" {
  count             = length(local.all_zones)
  name              = "${var.base_name}-${local.all_zones[count.index]}"
  vpc_id            = alicloud_vpc.vpc.id
  cidr_block        = cidrsubnet(var.vpc_cidr, var.subnet_netmask_bits, var.subnet_offset + count.index)
  availability_zone = local.all_zones[count.index]
}

Alicloudではsubnetをvswitchと呼ぶらしい。
ゾーンの数分vswitchを作成している。ここでのミソは、vswitchのCIDRをcidrsubnet関数を使って生成しているところ。
VPCのCIDRが10.10.0.0/16の場合、bits=8,offset=0とすると、

  • 10.10.0.0/24
  • 10.10.1.0/24
  • 10.10.2.0/24
  •   :

とゾーンの数だけCIDRを生成してくれる。上で「よしなに」と書いたのはcidrsubnetの働きを指している。

main_aws.tf
# subnetの作成
resource "aws_subnet" "subnet" {
  count                   = length(local.all_zones)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = cidrsubnet(var.vpc_cidr, var.subnet_netmask_bits, var.subnet_offset + count.index)
  availability_zone       = local.all_zones[count.index]
  map_public_ip_on_launch = true
  tags = map(
    "Name", "${var.base_name}-${local.all_zones[count.index]}",
  )
}

Alicloudとほとんど変わらない。
subnet.PNG

main.tfのコード全体

main_alicloud.tf
# Alicloud Providerの設定
provider "alicloud" {
  access_key = var.alicloud_access_key
  secret_key = var.alicloud_secret_key
  region     = var.alicloud_region
}

# 有効なゾーンを問い合わせ、local.all_zonesで参照する
data "alicloud_zones" "available" {
}
locals {
  all_zones = data.alicloud_zones.available.ids
}

# VPCの作成
resource "alicloud_vpc" "vpc" {
  name       = "${var.base_name}-vpc"
  cidr_block = var.vpc_cidr
}

# vswitch(subnet)の作成
resource "alicloud_vswitch" "vsw" {
  count             = length(local.all_zones)
  name              = "${var.base_name}-${local.all_zones[count.index]}"
  vpc_id            = alicloud_vpc.vpc.id
  cidr_block        = cidrsubnet(var.vpc_cidr, var.subnet_netmask_bits, var.subnet_offset + count.index)
  availability_zone = local.all_zones[count.index]
}
main_aws.tf
# AWS Providerの設定
provider "aws" {
  region = var.aws_region
}

# 有効なゾーンを問い合わせ、local.all_zonesで参照する
data "aws_availability_zones" "available" {
  state = "available"
}
locals {
  all_zones = data.aws_availability_zones.available.names
}

# VPCの作成
resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr
  tags = map(
    "Name", "${var.base_name}-vpc",
  )
}

# subnetの作成
resource "aws_subnet" "subnet" {
  count                   = length(local.all_zones)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = cidrsubnet(var.vpc_cidr, var.subnet_netmask_bits, var.subnet_offset + count.index)
  availability_zone       = local.all_zones[count.index]
  map_public_ip_on_launch = true
  tags = map(
    "Name", "${var.base_name}-${local.all_zones[count.index]}",
  )
}

variables.tfのコード全体

variables_alicloud.tf
# 共通設定
variable "base_name" {
  default     = "test"
}

variable "vpc_cidr" {
  default = "10.10.0.0/16"
}

variable "subnet_offset" {
  default     = 0
}

variable "subnet_netmask_bits" {
  default     = 8
}

# クラウドベンダー依存部分
variable "alicloud_region" {
  default = "ap-northeast-1"
}

variable "alicloud_access_key" {
  default     = "XXXXXXXXXXXXXXXXXXXXXXXX"
}

variable "alicloud_secret_key" {
  default     = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
}

コードにkeyを書くと、こーゆー時にひと手間かかるから環境変数にしよう!

variables_aws.tf
# 共通設定
variable "base_name" {
  default     = "test"
}

variable "vpc_cidr" {
  default = "10.10.0.0/16"
}

variable "subnet_offset" {
  default     = 0
}

variable "subnet_netmask_bits" {
  default     = 8
}

# クラウドベンダー依存部分
variable "aws_region" {
  default = "ap-northeast-1"
}

output - Alicloud

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

vpc = {
  "vpc" = {
    "cidr_block" = "10.10.0.0/16"
    "description" = ""
    "id" = "vpc-6wedpn6h4updttj8q26ej"
    "name" = "test-vpc"
    "resource_group_id" = "rg-acfns2xezp5njyq"
    "route_table_id" = "vtb-6wexwsiu3e97q1ed2canh"
    "router_id" = "vrt-6we4ws1qshqempzt2sd0s"
    "router_table_id" = "vtb-6wexwsiu3e97q1ed2canh"
  }
}
vsw = {
  "vsw" = [
    {
      "availability_zone" = "ap-northeast-1a"
      "cidr_block" = "10.10.0.0/24"
      "description" = ""
      "id" = "vsw-6weldnazsu76mf665lka6"
      "name" = "test-ap-northeast-1a"
      "vpc_id" = "vpc-6wedpn6h4updttj8q26ej"
    },
    {
      "availability_zone" = "ap-northeast-1b"
      "cidr_block" = "10.10.1.0/24"
      "description" = ""
      "id" = "vsw-6wewmrfku60rszr00wxzd"
      "name" = "test-ap-northeast-1b"
      "vpc_id" = "vpc-6wedpn6h4updttj8q26ej"
    },
  ]
}

コード

https://github.com/settembre21/terraform-vpc-subnet

さいごに

subnetまで作れたら後はインスタンス作ってLBで束ねるなり、なんなりできる。
regionとVPCのCIDRを指定するだけ。開発環境・テスト環境・・◯◯環境がすぐに構築できる。

terraformは、その記述自体が仕様書のようなものである。AWS向けに書いたコードをAlicloudチームへ渡すことで余計な説明が不要になるのではないか、と思う。これもインフラのコード化による産物だろう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした