LoginSignup
2
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-02-15

高可用性なサーバー配置

可用性が高いサーバーの配置として、ゾーン毎に立てるのは常套手段と思う。クラウドベンダーの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"
    },
  ]
}

コード

さいごに

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

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

2
1
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
2
1