前提
全体の概略はこちらから
Netowork部分の概略はこちらから
構成図
Module
main.tf
# vpc associated with rds
resource "aws_vpc" "vpc_database" {
cidr_block = var.vpc_cidr_database
tags = {
Name = "${var.project}-vpc-database"
Env = var.env
Account = var.account
Project = var.project
}
}
# subnet 1a associated with rds
resource "aws_subnet" "subnet_database1a" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_database1a
availability_zone = "ap-northeast-1a"
tags = {
Name = "${var.project}-subnet-${var.region}-database"
// ... 略
}
}
# subnet 1c associated with rds
resource "aws_subnet" "subnet_database1c" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_database1c
availability_zone = "ap-northeast-1c"
// ... 略
}
# subnet 1d associated with rds
resource "aws_subnet" "subnet_database1d" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_database1d
availability_zone = "ap-northeast-1d"
// ... 略
}
# subnet 1a associated with compute resources
resource "aws_subnet" "subnet_compute1a" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_compute1a
availability_zone = "ap-northeast-1a"
tags = {
Name = "${var.project}-subnet-${var.region}a-compute"
// ... 略
}
}
# subnet 1c associated with compute resources
resource "aws_subnet" "subnet_compute1c" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_compute1c
availability_zone = "ap-northeast-1c"
// ... 略
}
# subnet 1a associated with tgw attachment
resource "aws_subnet" "subnet_eni1a" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_eni1a
availability_zone = "ap-northeast-1a"
tags = {
Name = "${var.project}-subnet-${var.region}a-eni"
// ... 略
}
}
# subnet 1c associated with tgw attachment
resource "aws_subnet" "subnet_eni1c" {
vpc_id = aws_vpc.vpc_database.id
cidr_block = var.subnet_cidr_eni1c
availability_zone = "ap-northeast-1c"
// ... 略
}
# route table associated subnets for database
resource "aws_route_table" "rtb_database" {
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-rtb-database"
// ... 略
}
}
resource "aws_route_table_association" "database1a" {
subnet_id = aws_subnet.subnet_database1a.id
route_table_id = aws_route_table.rtb_database.id
}
resource "aws_route_table_association" "database1c" {
subnet_id = aws_subnet.subnet_database1c.id
route_table_id = aws_route_table.rtb_database.id
}
resource "aws_route_table_association" "database1d" {
subnet_id = aws_subnet.subnet_database1d.id
route_table_id = aws_route_table.rtb_database.id
}
# route table associated subnets for compute resources
resource "aws_route_table" "rtb_compute" {
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-rtb-compute"
// ... 略
}
}
resource "aws_route_table_association" "compute1a" {
subnet_id = aws_subnet.subnet_compute1a.id
route_table_id = aws_route_table.rtb_compute.id
}
resource "aws_route_table_association" "compute1c" {
subnet_id = aws_subnet.subnet_compute1c.id
route_table_id = aws_route_table.rtb_compute.id
}
# route table associated subnets for tgw attachment
resource "aws_route_table" "rtb_eni" {
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-rtb-eni"
// ... 略
}
}
resource "aws_route_table_association" "eni1a" {
subnet_id = aws_subnet.subnet_eni1a.id
route_table_id = aws_route_table.rtb_eni.id
}
resource "aws_route_table_association" "eni1c" {
subnet_id = aws_subnet.subnet_eni1c.id
route_table_id = aws_route_table.rtb_eni.id
}
# security group associated with rds
resource "aws_security_group" "sg_rds" {
name = "${var.project}-sg-rds"
description = "security group to be attached to RDS"
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-sg-rds"
// ... 略
}
}
resource "aws_vpc_security_group_ingress_rule" "rds" {
security_group_id = aws_security_group.sg_rds.id
referenced_security_group_id = aws_security_group.sg_rdsproxy.id
from_port = 5432
ip_protocol = "tcp"
to_port = 5432
}
# security group associated with rds proxy
resource "aws_security_group" "sg_rdsproxy" {
name = "${var.project}-sg-rdsproxy"
description = "security group to be attached to rds proxy"
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-sg-rdsproxy"
// ... 略
}
}
resource "aws_vpc_security_group_ingress_rule" "rdsproxy" {
security_group_id = aws_security_group.sg_rdsproxy.id
referenced_security_group_id = aws_security_group.sg_compute.id
from_port = 5432
ip_protocol = "tcp"
to_port = 5432
}
# security group associated with compute resources
resource "aws_security_group" "sg_compute" {
name = "${var.project}-sg-compute"
description = "security group to be attached to compute resources in database vpc"
vpc_id = aws_vpc.vpc_database.id
egress {
description = "Access to AWS resources via api"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.project}-sg-compute"
// ... 略
}
}
resource "aws_vpc_security_group_egress_rule" "compute_posgre" {
security_group_id = aws_security_group.sg_compute.id
referenced_security_group_id = aws_security_group.sg_rdsproxy.id
from_port = 5432
ip_protocol = "tcp"
to_port = 5432
}
# security group associated with vpc endpoint
resource "aws_security_group" "sg_endpoint" {
name = "${var.project}-sg-endpoint"
description = "security group to be attached to interface-type VPC endpoint"
vpc_id = aws_vpc.vpc_database.id
tags = {
Name = "${var.project}-sg-endpoint"
// ... 略
}
}
resource "aws_vpc_security_group_ingress_rule" "endpoint" {
security_group_id = aws_security_group.sg_endpoint.id
cidr_ipv4 = var.vpc_cidr_database
from_port = 443
ip_protocol = "tcp"
to_port = 443
}
# security group associated with network interface
resource "aws_security_group" "sg_eni" {
name = "${var.project}-sg-eni"
description = "security group to be attached to network interface in VPC of database"
vpc_id = aws_vpc.vpc_database.id
egress {
description = "Access to the Internet via Tgw"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.project}-sg-eni"
// ... 略
}
}
# network interface allocated in az 1a
resource "aws_network_interface" "a" {
subnet_id = aws_subnet.subnet_eni1a.id
security_groups = [aws_security_group.sg_eni.id]
tags = {
Name = "${var.project}-eni-database-${var.region}a"
// ... 略
}
}
# network interface allocated in az 1a
resource "aws_network_interface" "c" {
subnet_id = aws_subnet.subnet_eni1c.id
security_groups = [aws_security_group.sg_eni.id]
// ... 略
}
variable.tf
# common variable
variable "project" {
type = string
description = "project name"
}
variable "account" {
type = string
description = "prod or no-prod"
}
variable "env" {
type = string
description = "dev, test, stage or prod"
}
variable "region" {
type = string
description = "aws region which resources are allocated in"
}
# variables of cidr
variable "vpc_cidr_database" {
type = string
description = "cidr of vpc associated with rds"
}
variable "subnet_cidr_database1a" {
type = string
description = "cidr of subnet 1a associated with rds"
}
variable "subnet_cidr_database1c" {
type = string
description = "cidr of subnet 1c associated with rds"
}
variable "subnet_cidr_database1d" {
type = string
description = "cidr of subnet 1d associated with rds"
}
variable "subnet_cidr_compute1a" {
type = string
description = "cidr of subnet 1a associated with compute resources"
}
variable "subnet_cidr_compute1c" {
type = string
description = "cidr of subnet 1c associated with compute resources"
}
variable "subnet_cidr_eni1a" {
type = string
description = "cidr of subnet 1a associated with network interface"
}
variable "subnet_cidr_eni1c" {
type = string
description = "cidr of subnet 1c associated with network interface"
}
outputs.tf
output "vpc_database_id"{
value = aws_vpc.vpc_database.id
description = "id of vpc associated with rds"
}
output "subnet_database1a_id"{
value = aws_subnet.subnet_database1a.id
description = "id of subnet 1a associated with rds"
}
output "subnet_database1c_id"{
value = aws_subnet.subnet_database1c.id
description = "id of subnet 1c associated with rds"
}
output "subnet_database1d_id"{
value = aws_subnet.subnet_database1d.id
description = "id of subnet 1d associated with rds"
}
output "subnet_compute1a_id"{
value = aws_subnet.subnet_compute1a.id
description = "id of subnet 1a associated with compute resources"
}
output "subnet_compute1c_id"{
value = aws_subnet.subnet_compute1c.id
description = "id of subnet 1c associated with compute resources"
}
output "subnet_eni1a_id"{
value = aws_subnet.subnet_eni1a.id
description = "id of subnet 1a associated with tgw attachment"
}
output "subnet_eni1c_id"{
value = aws_subnet.subnet_eni1c.id
description = "id of subnet 1c associated with tgw attachment"
}
output "rtb_compute_id" {
value = aws_route_table.rtb_compute.id
description = "id of route table associated with subnets for compute resources"
}
output "sg_rds_id"{
value = aws_security_group.sg_rds.id
description = "id of security group associated with subnets for rds"
}
output "sg_rdsproxy_id"{
value = aws_security_group.sg_rdsproxy.id
description = "id of security group associated with subnets for rds proxy"
}
output "sg_compute_id"{
value = aws_security_group.sg_compute.id
description = "id of security group associated with subnets for compute resources"
}
output "sg_endpoint_id" {
value = aws_security_group.sg_endpoint.id
description = "id of security group associated with subnets for vpc endpoint"
}
Import コマンド
基本は👇
$ terraform import module.vpc_database.{resourceタイプ}.{resource名} {importするresourceのID}
以下のリソースは注意!
- aws_route_table_association
ImportするリソースIDはサブネットID/ルートテーブルID
$ terraform import module.vpc_database.aws_route_table_association.database1a subnet-***/rtb-***
他Moduleで構築したリソース
-
インターネットへのアウトバウンド通信のroute
- Transit GatewayのIDが必要なため、Transit Gatewayが作成されるまで。作成不可
- アウトバウンド通信の要件 or 開発が進むまでコストのかかるTransit Gatewayは不要
- 開発 or サービスのライフサイクル的に、Transit Gatewayの集約化とdatabase VPCなら、database VPCのほうが先に構築される
-
VPC endpoint
- コンピュートリソースが通信するAWSリソースはプロジェクトのライフサイクル or 開発工程で増減する
- それらのリソースをすべて最初から予測するのは不可能
- 一度作成したModule化リソースを再編集するのは避けたい