[terraform] AWSで3層ネットワーク構成を構築するmoduleを書いてみた
インフラエンジニアの寺岡です。
今回はterraformのmoduleについてのお話しです。
AWSのネットワークをPublic/DMZ/Privateの3層に分割する構成を一気に構築できる
かつどの案件でも使いまわせるようなmoduleを自作しましたのでまとめておきますー。
当記事に記載するコードを実行すると以下のような構成をAWS上にデプロイすることが出来ます。
マルチAZかつDMZのsubnetはNATGatewayを経由して外部と通信を行います。
Publicのsubnetは直接InternetGatewayと通信を行い
Privateのsubnetはローカル間通信のみとなっています。
一見複雑そうですが割とよく見る構成ではないでしょうか。
この構成をterraformでモジュール化した結果が以下のようになります。
■moduleに渡す値の変数を定義する
まずはmoduleに渡すための値をvariableで定義しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | variable "vpc_config" { default = { project = "tf-moduletest" environment = "stg" cidr_block = "10.10.0.0/16" } } variable "availability_zones" { default = ["ap-northeast-1a","ap-northeast-1c"] } variable "public_subnets" { default = ["10.10.0.0/20","10.10.16.0/20"] } variable "dmz_subnets" { default = ["10.10.32.0/20","10.10.48.0/20"] } variable "private_subnets" { default = ["10.10.64.0/20","10.10.80.0/20"] } |
■moduleを記述する
この部分が今回の本題です。
variableで定義した値を元にresourceを構築するだけなので
基本的にどの案件でも使いまわすことが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | ###### # VPC ###### resource "aws_vpc" "vpc" { cidr_block = "${var.vpc_config["cidr_block"]}" tags { Name = "vpc-${var.vpc_config["project"]}-${var.vpc_config["environment"]}" } } ################ # Public subnet ################ resource "aws_subnet" "public" { count = "${length(var.public_subnets)}" vpc_id = "${aws_vpc.vpc.id}" cidr_block = "${element(var.public_subnets, count.index)}" availability_zone = "${element(var.availability_zones, count.index)}" map_public_ip_on_launch = "true" tags { Name = "subnet-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-public-${substr(element(var.availability_zones, count.index),-1,1)}" } } ################ # DMZ subnet ################ resource "aws_subnet" "dmz" { count = "${length(var.dmz_subnets)}" vpc_id = "${aws_vpc.vpc.id}" cidr_block = "${element(var.dmz_subnets, count.index)}" availability_zone = "${element(var.availability_zones, count.index)}" tags { Name = "subnet-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-dmz-${substr(element(var.availability_zones, count.index),-1,1)}" } } ################ # Private subnet ################ resource "aws_subnet" "private" { count = "${length(var.private_subnets)}" vpc_id = "${aws_vpc.vpc.id}" cidr_block = "${element(var.private_subnets, count.index)}" availability_zone = "${element(var.availability_zones, count.index)}" tags { Name = "subnet-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-private-${substr(element(var.availability_zones, count.index),-1,1)}" } } ############################### # Public routes and association ############################### resource "aws_route_table" "public" { vpc_id = "${aws_vpc.vpc.id}" tags { Name = "rtb-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-public" } } resource "aws_internet_gateway" "internet_gateway" { vpc_id = "${aws_vpc.vpc.id}" tags { Name = "igw-${var.vpc_config["project"]}-${var.vpc_config["environment"]}" } } resource "aws_route" "public_internet_gateway" { route_table_id = "${aws_route_table.public.id}" destination_cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.internet_gateway.id}" } resource "aws_route_table_association" "public" { count = "${length(var.public_subnets)}" subnet_id = "${element(aws_subnet.public.*.id, count.index)}" route_table_id = "${aws_route_table.public.id}" } ############################ # DMZ routes and association ############################ resource "aws_route_table" "dmz" { count = "${length(var.dmz_subnets)}" vpc_id = "${aws_vpc.vpc.id}" tags { Name = "rtb-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-dmz-${substr(element(var.availability_zones, count.index),-1,1)}" } } resource "aws_eip" "nat" { count = "${length(var.dmz_subnets)}" vpc = true } resource "aws_nat_gateway" "nat_gateway" { count = "${length(var.dmz_subnets)}" allocation_id = "${element(aws_eip.nat.*.id, count.index)}" subnet_id = "${element(aws_subnet.public.*.id, count.index)}" tags { Name = "nat-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-public-${substr(element(var.availability_zones, count.index),-1,1)}" } } resource "aws_route" "dmz_nat_gateway" { count = "${length(var.dmz_subnets)}" route_table_id = "${element(aws_route_table.dmz.*.id, count.index)}" destination_cidr_block = "0.0.0.0/0" gateway_id = "${element(aws_nat_gateway.nat_gateway.*.id, count.index)}" } resource "aws_route_table_association" "dmz" { count = "${length(var.dmz_subnets)}" subnet_id = "${element(aws_subnet.dmz.*.id, count.index)}" route_table_id = "${element(aws_route_table.dmz.*.id, count.index)}" } ################################ # Private routes and association ################################ resource "aws_route_table" "private" { vpc_id = "${aws_vpc.vpc.id}" tags { Name = "rtb-${var.vpc_config["project"]}-${var.vpc_config["environment"]}-private" } } resource "aws_route_table_association" "private" { count = "${length(var.private_subnets)}" subnet_id = "${element(aws_subnet.private.*.id, count.index)}" route_table_id = "${aws_route_table.private.id}" } |
■記述したmoduleを呼び出す
terraformでmoduleを呼びだす場合は以下のような記述をします。
sourceでmoduleを記述した.tfファイルを格納しているディレクトリを指定して
variableで指定したmoduleを実行するために必要な変数を渡すだけです。
1 2 3 4 5 6 7 8 | module "vpc" { source = "../modules/network/vpc/" vpc_config = "${var.vpc_config}" availability_zones = "${var.availability_zones}" public_subnets = "${var.public_subnets}" dmz_subnets = "${var.dmz_subnets}" private_subnets = "${var.private_subnets}" } |
たったこれだけです、後は必殺のterraform applyを決めてあげてください。
。。。。以上です。
この記事がお役に立てば【 いいね 】のご協力をお願いいたします!