AWS 3 Tier Architecture
使用說明
建置架構
目錄結構
three_tier
├── main.tf
└── vpc
├── igw.tf
├── route_Private.tf
├── route_Public.tf
├── subnet_Private.tf
├── subnet_Public.tf
├── variable.tf
└── versions.tf
組態檔內容
main.tf
#Define provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-1"
}
# 這里可以定義主模塊的其他資源和配置
# 例如,你可以在這里定義 EC2 實例、RDS 資料庫等其他 AWS 資源
# 引用 vpc 子模塊
module "vpc" {
source = "./vpc" # 指定 vpc 子模塊的路徑。
}
variables.tf
##########################
##### VPC CIDR Block #####
##########################
variable "vpc_cidr" {
default = "10.0.0.0/16"
description = "VPC_cidr block"
type = string
}
##################
##### Subnet #####
##################
variable "public-subnet1" {
default = "10.0.1.0/24"
description = "public-subnet-A"
type = string
}
variable "public-subnet2" {
default = "10.0.2.0/24"
description = "public-subnet-B"
type = string
}
variable "private-subnet1" {
default = "10.0.3.0/24"
description = "private-subnet-A"
type = string
}
variable "private-subnet2" {
default = "10.0.4.0/24"
description = "private-subnet-B"
type = string
}
vpc.tf
#VPC
resource "aws_vpc" "vpc-block" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "tf-test-vpc"
}
}
## output
output "vpc_id" {
value = aws_vpc.vpc-block.tags["Name"]
}
subnet_Public.tf
#2 Public Subnets
resource "aws_subnet" "public-subnet1" {
tags = {
Name = "tf-test-PublicSubnet-A" # 子網的名稱
}
vpc_id = aws_vpc.vpc-block.id
cidr_block = var.public-subnet1
availability_zone = "us-east-1a"
}
resource "aws_subnet" "public-subnet2" {
tags = {
Name = "tf-test-PublicSubnet-B" # 子網的名稱
}
vpc_id = aws_vpc.vpc-block.id
cidr_block = var.public-subnet2
availability_zone = "us-east-1b"
}
## Output
output "public-subnet1_name" {
value = aws_subnet.public-subnet1.tags["Name"]
}
output "public-subnet2_name" {
value = aws_subnet.public-subnet2.tags["Name"]
}
subnet_Private.tf
# Private Subnets
resource "aws_subnet" "private-subnet1" {
tags = {
Name = "tf-test-PrivateSubnet-A" # 子網的名稱
}
vpc_id = aws_vpc.vpc-block.id
cidr_block = var.private-subnet1
availability_zone = "us-east-1a"
}
resource "aws_subnet" "private-subnet2" {
tags = {
Name = "tf-test-PrivateSubnet-B" # 子網的名稱
}
vpc_id = aws_vpc.vpc-block.id
cidr_block = var.private-subnet2
availability_zone = "us-east-1b"
}
## Output
output "private-subnet1_name" {
value = aws_subnet.private-subnet1.tags["Name"]
}
output "private-subnet2_name" {
value = aws_subnet.private-subnet2.tags["Name"]
}
route_Public.tf
# route_Public.tf
#######################
##### Route Table #####
#######################
# 創建公共路由表
resource "aws_route_table" "public-subnet-route-table" {
vpc_id = aws_vpc.vpc-block.id
tags = {
Name = "tf-test-Route-Public"
}
}
# 添加路由規則
resource "aws_route" "public-subnet-default-route" {
route_table_id = aws_route_table.public-subnet-route-table.id
destination_cidr_block = "0.0.0.0/0" # 所有流量
gateway_id = aws_internet_gateway.igw.id # 通過 Internet Gateway 出去
}
###################################
##### Route table association #####
###################################
# 將子網與路由表關聯
resource "aws_route_table_association" "public-subnet1-route-table-association" {
subnet_id = aws_subnet.public-subnet1.id
route_table_id = aws_route_table.public-subnet-route-table.id
}
resource "aws_route_table_association" "public-subnet2-route-table-association" {
subnet_id = aws_subnet.public-subnet2.id
route_table_id = aws_route_table.public-subnet-route-table.id
}
route_Private.tf
#######################
##### Route Table #####
#######################
resource "aws_route_table" "private-route-table" {
vpc_id = aws_vpc.vpc-block.id
tags = {
Name = "tf-test-Route-Private"
}
}
###################################
##### Route table association #####
###################################
# 將子網與路由表關聯
resource "aws_route_table_association" "private-subnet1-route-table-association" {
subnet_id = aws_subnet.private-subnet1.id
route_table_id = aws_route_table.private-route-table.id
}
resource "aws_route_table_association" "private-subnet2-route-table-association" {
subnet_id = aws_subnet.private-subnet2.id
route_table_id = aws_route_table.private-route-table.id
}
igw.tf
#Internet Gateway
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.vpc-block.id
tags = {
Name = "main"
}
}
Terraform 指令
- terraform init
terraform apply
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.vpc.aws_internet_gateway.gw will be created
+ resource "aws_internet_gateway" "gw" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "main"
}
+ tags_all = {
+ "Name" = "main"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_route.public-subnet-default-route will be created
+ resource "aws_route" "public-subnet-default-route" {
+ destination_cidr_block = "0.0.0.0/0"
+ gateway_id = (known after apply)
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = (known after apply)
+ state = (known after apply)
}
# module.vpc.aws_route_table.private-route-table will be created
+ resource "aws_route_table" "private-route-table" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "tf-test-Route-Private"
}
+ tags_all = {
+ "Name" = "tf-test-Route-Private"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_route_table.public-subnet-route-table will be created
+ resource "aws_route_table" "public-subnet-route-table" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "tf-test-Route-Public"
}
+ tags_all = {
+ "Name" = "tf-test-Route-Public"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_route_table_association.private-subnet1-route-table-association will be created
+ resource "aws_route_table_association" "private-subnet1-route-table-association" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.private-subnet2-route-table-association will be created
+ resource "aws_route_table_association" "private-subnet2-route-table-association" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.public-subnet1-route-table-association will be created
+ resource "aws_route_table_association" "public-subnet1-route-table-association" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.public-subnet2-route-table-association will be created
+ resource "aws_route_table_association" "public-subnet2-route-table-association" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_subnet.private-subnet1 will be created
+ resource "aws_subnet" "private-subnet1" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "us-east-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.3.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "tf-test-PrivateSubnet-A"
}
+ tags_all = {
+ "Name" = "tf-test-PrivateSubnet-A"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.private-subnet2 will be created
+ resource "aws_subnet" "private-subnet2" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "us-east-1b"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.4.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "tf-test-PrivateSubnet-B"
}
+ tags_all = {
+ "Name" = "tf-test-PrivateSubnet-B"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.public-subnet1 will be created
+ resource "aws_subnet" "public-subnet1" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "us-east-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.1.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "tf-test-PublicSubnet-A"
}
+ tags_all = {
+ "Name" = "tf-test-PublicSubnet-A"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_subnet.public-subnet2 will be created
+ resource "aws_subnet" "public-subnet2" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "us-east-1b"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.2.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "tf-test-PublicSubnet-B"
}
+ tags_all = {
+ "Name" = "tf-test-PublicSubnet-B"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_vpc.vpc-block will be created
+ resource "aws_vpc" "vpc-block" {
+ arn = (known after apply)
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ enable_network_address_usage_metrics = (known after apply)
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_network_border_group = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "tf-test-vpc"
}
+ tags_all = {
+ "Name" = "tf-test-vpc"
}
}
Plan: 13 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
module.vpc.aws_vpc.vpc-block: Creating...
module.vpc.aws_vpc.vpc-block: Still creating... [10s elapsed]
module.vpc.aws_vpc.vpc-block: Creation complete after 14s [id=vpc-07130f9a51d598818]
module.vpc.aws_internet_gateway.gw: Creating...
module.vpc.aws_subnet.public-subnet1: Creating...
module.vpc.aws_route_table.public-subnet-route-table: Creating...
module.vpc.aws_subnet.private-subnet1: Creating...
module.vpc.aws_subnet.private-subnet2: Creating...
module.vpc.aws_route_table.private-route-table: Creating...
module.vpc.aws_subnet.public-subnet2: Creating...
module.vpc.aws_internet_gateway.gw: Creation complete after 2s [id=igw-02e9ff7e18f473f62]
module.vpc.aws_subnet.private-subnet1: Creation complete after 2s [id=subnet-056f2b43d7c356a8a]
module.vpc.aws_subnet.public-subnet1: Creation complete after 2s [id=subnet-0380bf06347e7f60e]
module.vpc.aws_route_table.public-subnet-route-table: Creation complete after 2s [id=rtb-040eb67c02a0b433c]
module.vpc.aws_subnet.public-subnet2: Creation complete after 2s [id=subnet-0ea21be20b97a7f1a]
module.vpc.aws_subnet.private-subnet2: Creation complete after 2s [id=subnet-0f3661e926b68d6f9]
module.vpc.aws_route_table_association.public-subnet1-route-table-association: Creating...
module.vpc.aws_route_table_association.public-subnet2-route-table-association: Creating...
module.vpc.aws_route.public-subnet-default-route: Creating...
module.vpc.aws_route_table.private-route-table: Creation complete after 2s [id=rtb-08a685a62c849c949]
module.vpc.aws_route_table_association.private-subnet2-route-table-association: Creating...
module.vpc.aws_route_table_association.private-subnet1-route-table-association: Creating...
module.vpc.aws_route_table_association.public-subnet2-route-table-association: Creation complete after 1s [id=rtbassoc-0dc0becb5ab37a31a]
module.vpc.aws_route_table_association.private-subnet2-route-table-association: Creation complete after 1s [id=rtbassoc-0e5fcc59545411ff8]
module.vpc.aws_route_table_association.public-subnet1-route-table-association: Creation complete after 1s [id=rtbassoc-0ce38fafb5406d184]
module.vpc.aws_route_table_association.private-subnet1-route-table-association: Creation complete after 1s [id=rtbassoc-0992ef7af2c264f05]
module.vpc.aws_route.public-subnet-default-route: Creation complete after 1s [id=r-rtb-040eb67c02a0b433c1080289494]
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.
terraform show
# module.vpc.aws_internet_gateway.gw:
resource "aws_internet_gateway" "gw" {
arn = "arn:aws:ec2:us-east-1:304317510309:internet-gateway/igw-02e9ff7e18f473f62"
id = "igw-02e9ff7e18f473f62"
owner_id = "304317510309"
tags = {
"Name" = "main"
}
tags_all = {
"Name" = "main"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_route.public-subnet-default-route:
resource "aws_route" "public-subnet-default-route" {
destination_cidr_block = "0.0.0.0/0"
gateway_id = "igw-02e9ff7e18f473f62"
id = "r-rtb-040eb67c02a0b433c1080289494"
origin = "CreateRoute"
route_table_id = "rtb-040eb67c02a0b433c"
state = "active"
}
# module.vpc.aws_route_table.private-route-table:
resource "aws_route_table" "private-route-table" {
arn = "arn:aws:ec2:us-east-1:304317510309:route-table/rtb-08a685a62c849c949"
id = "rtb-08a685a62c849c949"
owner_id = "304317510309"
propagating_vgws = []
route = []
tags = {
"Name" = "tf-test-Route-Private"
}
tags_all = {
"Name" = "tf-test-Route-Private"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_route_table.public-subnet-route-table:
resource "aws_route_table" "public-subnet-route-table" {
arn = "arn:aws:ec2:us-east-1:304317510309:route-table/rtb-040eb67c02a0b433c"
id = "rtb-040eb67c02a0b433c"
owner_id = "304317510309"
propagating_vgws = []
route = []
tags = {
"Name" = "tf-test-Route-Public"
}
tags_all = {
"Name" = "tf-test-Route-Public"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_route_table_association.private-subnet1-route-table-association:
resource "aws_route_table_association" "private-subnet1-route-table-association" {
id = "rtbassoc-0992ef7af2c264f05"
route_table_id = "rtb-08a685a62c849c949"
subnet_id = "subnet-056f2b43d7c356a8a"
}
# module.vpc.aws_route_table_association.private-subnet2-route-table-association:
resource "aws_route_table_association" "private-subnet2-route-table-association" {
id = "rtbassoc-0e5fcc59545411ff8"
route_table_id = "rtb-08a685a62c849c949"
subnet_id = "subnet-0f3661e926b68d6f9"
}
# module.vpc.aws_route_table_association.public-subnet1-route-table-association:
resource "aws_route_table_association" "public-subnet1-route-table-association" {
id = "rtbassoc-0ce38fafb5406d184"
route_table_id = "rtb-040eb67c02a0b433c"
subnet_id = "subnet-0380bf06347e7f60e"
}
# module.vpc.aws_route_table_association.public-subnet2-route-table-association:
resource "aws_route_table_association" "public-subnet2-route-table-association" {
id = "rtbassoc-0dc0becb5ab37a31a"
route_table_id = "rtb-040eb67c02a0b433c"
subnet_id = "subnet-0ea21be20b97a7f1a"
}
# module.vpc.aws_subnet.private-subnet1:
resource "aws_subnet" "private-subnet1" {
arn = "arn:aws:ec2:us-east-1:304317510309:subnet/subnet-056f2b43d7c356a8a"
assign_ipv6_address_on_creation = false
availability_zone = "us-east-1a"
availability_zone_id = "use1-az2"
cidr_block = "10.0.3.0/24"
enable_dns64 = false
enable_lni_at_device_index = 0
enable_resource_name_dns_a_record_on_launch = false
enable_resource_name_dns_aaaa_record_on_launch = false
id = "subnet-056f2b43d7c356a8a"
ipv6_native = false
map_customer_owned_ip_on_launch = false
map_public_ip_on_launch = false
owner_id = "304317510309"
private_dns_hostname_type_on_launch = "ip-name"
tags = {
"Name" = "tf-test-PrivateSubnet-A"
}
tags_all = {
"Name" = "tf-test-PrivateSubnet-A"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_subnet.private-subnet2:
resource "aws_subnet" "private-subnet2" {
arn = "arn:aws:ec2:us-east-1:304317510309:subnet/subnet-0f3661e926b68d6f9"
assign_ipv6_address_on_creation = false
availability_zone = "us-east-1b"
availability_zone_id = "use1-az4"
cidr_block = "10.0.4.0/24"
enable_dns64 = false
enable_lni_at_device_index = 0
enable_resource_name_dns_a_record_on_launch = false
enable_resource_name_dns_aaaa_record_on_launch = false
id = "subnet-0f3661e926b68d6f9"
ipv6_native = false
map_customer_owned_ip_on_launch = false
map_public_ip_on_launch = false
owner_id = "304317510309"
private_dns_hostname_type_on_launch = "ip-name"
tags = {
"Name" = "tf-test-PrivateSubnet-B"
}
tags_all = {
"Name" = "tf-test-PrivateSubnet-B"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_subnet.public-subnet1:
resource "aws_subnet" "public-subnet1" {
arn = "arn:aws:ec2:us-east-1:304317510309:subnet/subnet-0380bf06347e7f60e"
assign_ipv6_address_on_creation = false
availability_zone = "us-east-1a"
availability_zone_id = "use1-az2"
cidr_block = "10.0.1.0/24"
enable_dns64 = false
enable_lni_at_device_index = 0
enable_resource_name_dns_a_record_on_launch = false
enable_resource_name_dns_aaaa_record_on_launch = false
id = "subnet-0380bf06347e7f60e"
ipv6_native = false
map_customer_owned_ip_on_launch = false
map_public_ip_on_launch = false
owner_id = "304317510309"
private_dns_hostname_type_on_launch = "ip-name"
tags = {
"Name" = "tf-test-PublicSubnet-A"
}
tags_all = {
"Name" = "tf-test-PublicSubnet-A"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_subnet.public-subnet2:
resource "aws_subnet" "public-subnet2" {
arn = "arn:aws:ec2:us-east-1:304317510309:subnet/subnet-0ea21be20b97a7f1a"
assign_ipv6_address_on_creation = false
availability_zone = "us-east-1b"
availability_zone_id = "use1-az4"
cidr_block = "10.0.2.0/24"
enable_dns64 = false
enable_lni_at_device_index = 0
enable_resource_name_dns_a_record_on_launch = false
enable_resource_name_dns_aaaa_record_on_launch = false
id = "subnet-0ea21be20b97a7f1a"
ipv6_native = false
map_customer_owned_ip_on_launch = false
map_public_ip_on_launch = false
owner_id = "304317510309"
private_dns_hostname_type_on_launch = "ip-name"
tags = {
"Name" = "tf-test-PublicSubnet-B"
}
tags_all = {
"Name" = "tf-test-PublicSubnet-B"
}
vpc_id = "vpc-07130f9a51d598818"
}
# module.vpc.aws_vpc.vpc-block:
resource "aws_vpc" "vpc-block" {
arn = "arn:aws:ec2:us-east-1:304317510309:vpc/vpc-07130f9a51d598818"
assign_generated_ipv6_cidr_block = false
cidr_block = "10.0.0.0/16"
default_network_acl_id = "acl-0b11b03eedf6f46ef"
default_route_table_id = "rtb-0b9a0e7a42bef5280"
default_security_group_id = "sg-0029a2b26c1a58ef5"
dhcp_options_id = "dopt-091fd5e6823f88133"
enable_classiclink = false
enable_classiclink_dns_support = false
enable_dns_hostnames = true
enable_dns_support = true
enable_network_address_usage_metrics = false
id = "vpc-07130f9a51d598818"
instance_tenancy = "default"
ipv6_netmask_length = 0
main_route_table_id = "rtb-0b9a0e7a42bef5280"
owner_id = "304317510309"
tags = {
"Name" = "tf-test-vpc"
}
tags_all = {
"Name" = "tf-test-vpc"
}
}
- terraform destroy