Compute State

Next we'll move onto our Compute state. For us, this means managing our two EC2 instances.

Since we don't have a way to access the VPC output directly via the module syntax (module.vpc.vpc_id, for example), we need a way to get that data.

Luckily we can use data sources for that!

We'll use data sources for:

  1. aws_vpc
  2. aws_subnet_ids
  3. aws_security_groups

File production/compute/main.tf

Just like before, we copy the cloudcasts.tf file, rename it main.tf, and remove any excess items. In this case, it's removing the VPC module usage.

Then we make adjustments to get the needed data so we can create our EC2 servers within the VPC that we created in the last video.

1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "3.25.0"
6 }
7 }
8 
9 backend "s3" {
10 profile = "cloudcasts"
11 region = "us-east-2"
12 }
13}
14 
15provider "aws" {
16 profile = "cloudcasts"
17 region = "us-east-2"
18}
19 
20variable "infra_env" {
21 type = string
22 description = "infrastructure environment"
23 default = "production"
24}
25 
26variable default_region {
27 type = string
28 description = "the region this infrastructure is in"
29 default = "us-east-2"
30}
31 
32 
33data "aws_ami" "app" {
34 most_recent = true
35 
36 filter {
37 name = "state"
38 values = ["available"]
39 }
40 
41 filter {
42 name = "tag:Component"
43 values = ["app"]
44 }
45 
46 filter {
47 name = "tag:Project"
48 values = ["cloudcast"]
49 }
50 
51 filter {
52 name = "tag:Environment"
53 values = ["staging"]
54 }
55 
56 owners = ["self"]
57}
58 
59# New data sources used:
60data "aws_vpc" "vpc" {
61 tags = {
62 Name = "cloudcasts-${var.infra_env}-vpc"
63 Project = "cloudcasts.io"
64 Environment = var.infra_env
65 ManagedBy = "terraform"
66 }
67}
68 
69data "aws_subnet_ids" "public_subnets" {
70 vpc_id = data.aws_vpc.vpc.id
71 
72 tags = {
73 Name = "cloudcasts-${var.infra_env}-vpc"
74 Project = "cloudcasts.io"
75 Environment = var.infra_env
76 ManagedBy = "terraform"
77 Role = "public"
78 }
79}
80 
81data "aws_subnet_ids" "private_subnets" {
82 vpc_id = data.aws_vpc.vpc.id
83 
84 tags = {
85 Name = "cloudcasts-${var.infra_env}-vpc"
86 Project = "cloudcasts.io"
87 Environment = var.infra_env
88 ManagedBy = "terraform"
89 Role = "private"
90 }
91}
92 
93data "aws_security_groups" "public_sg" {
94 tags = {
95 Name = "cloudcasts-${var.infra_env}-public-sg"
96 Role = "public"
97 Project = "cloudcasts.io"
98 Environment = var.infra_env
99 ManagedBy = "terraform"
100 }
101}
102 
103data "aws_security_groups" "private_sg" {
104 tags = {
105 Name = "cloudcasts-${var.infra_env}-private-sg"
106 Role = "private"
107 Project = "cloudcasts.io"
108 Environment = var.infra_env
109 ManagedBy = "terraform"
110 }
111}
112 
113module "ec2_app" {
114 source = "../../modules/ec2"
115 
116 infra_env = var.infra_env
117 infra_role = "web"
118 instance_size = "t3.small"
119 instance_ami = data.aws_ami.app.id
120 # instance_root_device_size = 12
121 subnets = data.aws_subnet_ids.public_subnets.ids
122 security_groups = data.aws_security_groups.public_sg.ids
123 tags = {
124 Name = "cloudcasts-${var.infra_env}-web"
125 }
126 create_eip = true
127}
128 
129module "ec2_worker" {
130 source = "../../modules/ec2"
131 
132 infra_env = var.infra_env
133 infra_role = "worker"
134 instance_size = "t3.large"
135 instance_ami = data.aws_ami.app.id
136 instance_root_device_size = 20
137 subnets = data.aws_subnet_ids.private_subnets.ids
138 security_groups = data.aws_security_groups.private_sg.ids
139 tags = {
140 Name = "cloudcasts-${var.infra_env}-worker"
141 }
142 create_eip = false
143}

File modules/vpc/main.tf

We also needed to add some additional tags to the public and private subnets that the VPC module creates. To do that, we found some variables we can use included in the community VPC module.

We could easily add some tags that way to differentiate public vs private subnets!

1module "vpc" {
2 source = "terraform-aws-modules/vpc/aws"
3 version = "2.77.0"
4 
5 # insert the 49 required variables here
6 name = "cloudcasts-${var.infra_env}-vpc"
7 cidr = var.vpc_cidr
8 
9 azs = var.azs
10 
11 # Single NAT Gateway, see docs linked above
12 enable_nat_gateway = true
13 single_nat_gateway = true
14 one_nat_gateway_per_az = false
15 
16 private_subnets = var.private_subnets
17 public_subnets = var.public_subnets
18 database_subnets = var.database_subnets
19 
20 tags = {
21 Name = "cloudcasts-${var.infra_env}-vpc"
22 Project = "cloudcasts.io"
23 Environment = var.infra_env
24 ManagedBy = "terraform"
25 }
26 
27 # NEW ITEMS HERE:
28 private_subnet_tags = {
29 Role = "private"
30 }
31 
32 public_subnet_tags = {
33 Role = "public"
34 }
35}

Then we can init/plan/apply these changes:

1# Apply our additional tags to our subnets:
2./run production compute plan
3./run production compute apply
4 
5# Init our new stage area, plan, and apply
6./run production compute init
7./run production compute plan
8./run production compute apply

Don't miss out

Sign up to learn when new content is released! Courses are in production now.