AWS VPC
Virtual Private Cloud (VPC)
An AWS VPC (Virtual Private Cloud) is a logically isolated virtual network dedicated to your AWS account. It mimics a traditional physical network inside a data center, giving you complete control over your IP addressing, subnets, routing, and security.
Core components
-
Subnets: Segments of your VPC IP address range.
-
Public Subnets: Connected to the internet via an Internet Gateway (used for web servers, load balancers).
-
Private Subnets: Isolated from direct internet access (used for databases, backend microservices).
-
-
Route Tables: Rules determining where network traffic from subnets or gateways is directed.
-
Internet Gateway (IGW): Allows communication between instances in your VPC and the internet.
-
NAT Gateway: Enables instances in a private subnet to connect to the internet (e.g., for software updates) while blocking external inbound traffic.
-
Security Controls:
-
Security Groups: Stateful virtual firewalls at the instance level (EC2, containers).
-
Network ACLs (NACLs): Stateless firewalls at the subnet level.
-
Terraform project
Objective
Provision a basic network architecture locally
- VPC with a Public Subnet
- Internet Gateway
- EC2 Instance
Tools
mkdir floci-terraform-vpc && cd floci-terraform-vpc
Provider setup
Set env vars
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
Floci setup - Docker Compose
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
environment:
FLOCI_STORAGE_MODE: hybrid
docker compose up -d
Add .gitignore
# Local .terraform directories
.terraform/
# Exclude local volume directory
data/
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Ignore transient lock info files created by terraform apply
.terraform.tfstate.lock.info
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Optional: ignore graph output files generated by `terraform graph`
# *.dot
# Optional: ignore plan files saved before destroying Terraform configuration
# Uncomment the line below if you want to ignore planout files.
# planout
providers.tf
provider "aws" {
access_key = "test"
secret_key = "test"
region = "us-east-1"
skip_credentials_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
s3_use_path_style = true
endpoints {
apigateway = "http://localhost:4566"
cloudformation = "http://localhost:4566"
cloudwatch = "http://localhost:4566"
dynamodb = "http://localhost:4566"
ec2 = "http://localhost:4566"
es = "http://localhost:4566"
iam = "http://localhost:4566"
kinesis = "http://localhost:4566"
lambda = "http://localhost:4566"
route53 = "http://localhost:4566"
s3 = "http://localhost:4566"
secretsmanager = "http://localhost:4566"
ses = "http://localhost:4566"
sns = "http://localhost:4566"
sqs = "http://localhost:4566"
ssm = "http://localhost:4566"
stepfunctions = "http://localhost:4566"
sts = "http://localhost:4566"
}
}
Initialize Terraform
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v6.61.0...
- Installed hashicorp/aws v6.61.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Create variables
variables.tf
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "vpc_cidr" {
type = string
default = "10.0.0.0/16"
}
variable "public_subnet_cidr" {
type = string
default = "10.0.1.0/24"
}
/16 (VPC): Provides 65,536 total IP addresses (10.0.0.0 to 10.0.255.255).
/24 (Subnet): Provides 256 total IP addresses (10.0.1.0 to 10.0.1.255).
Create VPC
vpc.tf
resource "aws_vpc" "dev_vpc" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
tags = {
Name = "dev-vpc"
}
}
terraform plan and apply
terraform plan
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:
# aws_vpc.dev_vpc will be created
+ resource "aws_vpc" "dev_vpc" {
+ 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_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)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-vpc"
}
+ tags_all = {
+ "Name" = "dev-vpc"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
terraform apply -auto-approve
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:
# aws_vpc.dev_vpc will be created
+ resource "aws_vpc" "dev_vpc" {
+ 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_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)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-vpc"
}
+ tags_all = {
+ "Name" = "dev-vpc"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_vpc.dev_vpc: Creating...
aws_vpc.dev_vpc: Creation complete after 0s [id=vpc-9de614ab]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Create Internet Gateway
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.dev_vpc.id
tags = {
Name = "dev-igw"
}
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
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:
# aws_internet_gateway.igw will be created
+ resource "aws_internet_gateway" "igw" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-igw"
}
+ tags_all = {
+ "Name" = "dev-igw"
}
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
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:
# aws_internet_gateway.igw will be created
+ resource "aws_internet_gateway" "igw" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-igw"
}
+ tags_all = {
+ "Name" = "dev-igw"
}
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_internet_gateway.igw: Creating...
aws_internet_gateway.igw: Creation complete after 0s [id=igw-e05f40c7]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Create Subnet
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.dev_vpc.id
cidr_block = var.public_subnet_cidr
map_public_ip_on_launch = true
tags = {
Name = "dev-public-subnet"
}
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
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:
# aws_subnet.public_subnet will be created
+ resource "aws_subnet" "public_subnet" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = (known after apply)
+ 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 = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = true
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-public-subnet"
}
+ tags_all = {
+ "Name" = "dev-public-subnet"
}
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
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:
# aws_subnet.public_subnet will be created
+ resource "aws_subnet" "public_subnet" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = (known after apply)
+ 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 = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = true
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ region = "us-east-1"
+ tags = {
+ "Name" = "dev-public-subnet"
}
+ tags_all = {
+ "Name" = "dev-public-subnet"
}
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_subnet.public_subnet: Creating...
aws_subnet.public_subnet: Still creating... [00m10s elapsed]
aws_subnet.public_subnet: Creation complete after 10s [id=subnet-adbcfd21]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Create Route Table and Association
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.dev_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "dev-public-rt"
}
}
resource "aws_route_table_association" "public_assoc" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.public_rt.id
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
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:
# aws_route_table.public_rt will be created
+ resource "aws_route_table" "public_rt" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ region = "us-east-1"
+ route = [
+ {
+ cidr_block = "0.0.0.0/0"
+ gateway_id = "igw-e05f40c7"
# (12 unchanged attributes hidden)
},
]
+ tags = {
+ "Name" = "dev-public-rt"
}
+ tags_all = {
+ "Name" = "dev-public-rt"
}
+ vpc_id = "vpc-9de614ab"
}
# aws_route_table_association.public_assoc will be created
+ resource "aws_route_table_association" "public_assoc" {
+ id = (known after apply)
+ region = "us-east-1"
+ route_table_id = (known after apply)
+ subnet_id = "subnet-adbcfd21"
}
Plan: 2 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
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:
# aws_route_table.public_rt will be created
+ resource "aws_route_table" "public_rt" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ region = "us-east-1"
+ route = [
+ {
+ cidr_block = "0.0.0.0/0"
+ gateway_id = "igw-e05f40c7"
# (12 unchanged attributes hidden)
},
]
+ tags = {
+ "Name" = "dev-public-rt"
}
+ tags_all = {
+ "Name" = "dev-public-rt"
}
+ vpc_id = "vpc-9de614ab"
}
# aws_route_table_association.public_assoc will be created
+ resource "aws_route_table_association" "public_assoc" {
+ id = (known after apply)
+ region = "us-east-1"
+ route_table_id = (known after apply)
+ subnet_id = "subnet-adbcfd21"
}
Plan: 2 to add, 0 to change, 0 to destroy.
aws_route_table.public_rt: Creating...
aws_route_table.public_rt: Creation complete after 0s [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Creating...
aws_route_table_association.public_assoc: Creation complete after 0s [id=rtbassoc-439ae214]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Create Security Group
ec2.tf
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP and SSH traffic"
vpc_id = aws_vpc.dev_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
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:
# aws_security_group.web_sg will be created
+ resource "aws_security_group" "web_sg" {
+ arn = (known after apply)
+ description = "Allow HTTP and SSH traffic"
+ egress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 0
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "-1"
+ security_groups = []
+ self = false
+ to_port = 0
# (1 unchanged attribute hidden)
},
]
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
# (1 unchanged attribute hidden)
},
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 80
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 80
# (1 unchanged attribute hidden)
},
]
+ name = "web-sg"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ region = "us-east-1"
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take
exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
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:
# aws_security_group.web_sg will be created
+ resource "aws_security_group" "web_sg" {
+ arn = (known after apply)
+ description = "Allow HTTP and SSH traffic"
+ egress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 0
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "-1"
+ security_groups = []
+ self = false
+ to_port = 0
# (1 unchanged attribute hidden)
},
]
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
# (1 unchanged attribute hidden)
},
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ from_port = 80
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 80
# (1 unchanged attribute hidden)
},
]
+ name = "web-sg"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ region = "us-east-1"
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = "vpc-9de614ab"
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_security_group.web_sg: Creating...
aws_security_group.web_sg: Creation complete after 0s [id=sg-3c57687c7fb5b2ca2]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Create EC2 Instance
resource "aws_instance" "web_server" {
ami = "ami-12345678"
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
tags = {
Name = "dev-web-server"
}
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_security_group.web_sg: Refreshing state... [id=sg-3c57687c7fb5b2ca2]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
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:
# aws_instance.web_server will be created
+ resource "aws_instance" "web_server" {
+ ami = "ami-12345678"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ disable_api_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ enable_primary_ipv6 = (known after apply)
+ force_destroy = false
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (known after apply)
+ iam_instance_profile = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_lifecycle = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ placement_group_id = (known after apply)
+ placement_partition_number = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ region = "us-east-1"
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ spot_instance_request_id = (known after apply)
+ subnet_id = "subnet-adbcfd21"
+ tags = {
+ "Name" = "dev-web-server"
}
+ tags_all = {
+ "Name" = "dev-web-server"
}
+ tenancy = (known after apply)
+ user_data_base64 = (known after apply)
+ user_data_replace_on_change = false
+ vpc_security_group_ids = [
+ "sg-3c57687c7fb5b2ca2",
]
+ capacity_reservation_specification (known after apply)
+ cpu_options (known after apply)
+ ebs_block_device (known after apply)
+ enclave_options (known after apply)
+ ephemeral_block_device (known after apply)
+ instance_market_options (known after apply)
+ maintenance_options (known after apply)
+ metadata_options (known after apply)
+ network_interface (known after apply)
+ primary_network_interface (known after apply)
+ private_dns_name_options (known after apply)
+ root_block_device (known after apply)
+ secondary_network_interface (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_security_group.web_sg: Refreshing state... [id=sg-3c57687c7fb5b2ca2]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
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:
# aws_instance.web_server will be created
+ resource "aws_instance" "web_server" {
+ ami = "ami-12345678"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ disable_api_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ enable_primary_ipv6 = (known after apply)
+ force_destroy = false
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (known after apply)
+ iam_instance_profile = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_lifecycle = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ placement_group_id = (known after apply)
+ placement_partition_number = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ region = "us-east-1"
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ spot_instance_request_id = (known after apply)
+ subnet_id = "subnet-adbcfd21"
+ tags = {
+ "Name" = "dev-web-server"
}
+ tags_all = {
+ "Name" = "dev-web-server"
}
+ tenancy = (known after apply)
+ user_data_base64 = (known after apply)
+ user_data_replace_on_change = false
+ vpc_security_group_ids = [
+ "sg-3c57687c7fb5b2ca2",
]
+ capacity_reservation_specification (known after apply)
+ cpu_options (known after apply)
+ ebs_block_device (known after apply)
+ enclave_options (known after apply)
+ ephemeral_block_device (known after apply)
+ instance_market_options (known after apply)
+ maintenance_options (known after apply)
+ metadata_options (known after apply)
+ network_interface (known after apply)
+ primary_network_interface (known after apply)
+ private_dns_name_options (known after apply)
+ root_block_device (known after apply)
+ secondary_network_interface (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_instance.web_server: Creating...
aws_instance.web_server: Still creating... [00m10s elapsed]
aws_instance.web_server: Still creating... [00m20s elapsed]
aws_instance.web_server: Still creating... [00m30s elapsed]
aws_instance.web_server: Creation complete after 39s [id=i-8e7ae0cc83a831907]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Create Outputs
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.dev_vpc.id
}
output "public_subnet_id" {
description = "The ID of the public subnet"
value = aws_subnet.public_subnet.id
}
output "instance_id" {
description = "The ID of the EC2 instance"
value = aws_instance.web_server.id
}
terraform plan
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_security_group.web_sg: Refreshing state... [id=sg-3c57687c7fb5b2ca2]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_instance.web_server: Refreshing state... [id=i-8e7ae0cc83a831907]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
Changes to Outputs:
+ instance_id = "i-8e7ae0cc83a831907"
+ public_subnet_id = "subnet-adbcfd21"
+ vpc_id = "vpc-9de614ab"
You can apply this plan to save these new output values to the Terraform state, without changing
any real infrastructure.
────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply -auto-approve
aws_vpc.dev_vpc: Refreshing state... [id=vpc-9de614ab]
aws_internet_gateway.igw: Refreshing state... [id=igw-e05f40c7]
aws_subnet.public_subnet: Refreshing state... [id=subnet-adbcfd21]
aws_security_group.web_sg: Refreshing state... [id=sg-3c57687c7fb5b2ca2]
aws_route_table.public_rt: Refreshing state... [id=rtb-c8bae0b5]
aws_route_table_association.public_assoc: Refreshing state... [id=rtbassoc-439ae214]
aws_instance.web_server: Refreshing state... [id=i-8e7ae0cc83a831907]
Changes to Outputs:
+ instance_id = "i-8e7ae0cc83a831907"
+ public_subnet_id = "subnet-adbcfd21"
+ vpc_id = "vpc-9de614ab"
You can apply this plan to save these new output values to the Terraform state, without changing
any real infrastructure.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
instance_id = "i-8e7ae0cc83a831907"
public_subnet_id = "subnet-adbcfd21"
vpc_id = "vpc-9de614ab"
terraform output
instance_id = "i-8e7ae0cc83a831907"
public_subnet_id = "subnet-adbcfd21"
vpc_id = "vpc-9de614ab"