AWSリソースをTerraformにImportする（Network関連_databaseVPC）

# 前提
全体の概略は[こちらから](https://qiita.com/hrkkanda/items/1ef47fd6213547396c99)
Netowork部分の概略は[こちらから](https://qiita.com/hrkkanda/items/64a252c5481fdd003e98)

# 構成図

# Module
### main.tf
```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
```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
```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 コマンド
基本は👇
```tf
$ terraform import module.vpc_database.{resourceタイプ}.{resource名} {importするresourceのID}
```

以下のリソースは注意！
- aws_route_table_association
ImportするリソースIDは`サブネットID/ルートテーブルID`
```tf
$ 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化リソースを再編集するのは避けたい