Module Clean Up

We need to do some cleanup in how we implement our modules:

  1. We'd like to be able to assign tags ad-hoc to our EC2 instances.
  2. We'd like to optionally create and associate an EIP with our EC2 instances.

File variables.tf

First we'll edit modules/ec2/variables.tf to add two variables. These will allow us to define some tags and say if we want an EIP created/associated to an instance.

1variable "tags" {
2 type = map(string)
3 default = {}
4 description = "tags for the ec2 instance"
5}
6 
7variable "create_eip" {
8 type = bool
9 default = false
10 description = "whether or create an EIP for the ec2 instance or not"
11}

File main.tf

Next, we'll update modules/ec2/main.tf to use the merge function, allowing us to set some default tags that can be over-written (or added to).

1 resource "aws_instance" "cloudcasts_web" {
2 ami = var.instance_ami
3 instance_type = var.instance_size
4  
5 root_block_device {
6 volume_size = var.instance_root_device_size
7 volume_type = "gp3"
8 }
9  
10 subnet_id = random_shuffle.subnets.result[0]
11 vpc_security_group_ids = var.security_groups
12  
13 lifecycle {
14 create_before_destroy = true
15 }
16  
17- tags = {
18- Name = "cloudcasts-${var.infra_env}"
19- Role = var.infra_role
20- Project = "cloudcasts.io"
21- Environment = var.infra_env
22- ManagedBy = "terraform"
23- }
24+ tags = merge(
25+ {
26+ Name = "cloudcasts-${var.infra_env}"
27+ Role = var.infra_role
28+ Project = "cloudcasts.io"
29+ Environment = var.infra_env
30+ ManagedBy = "terraform"
31+ },
32+ var.tags
33+ )
34 }
35  
36 resource "aws_eip" "cloudcasts_addr" {
37 # New: The use of count
38 count = (var.create_eip) ? 1 : 0
39 # We're not doing this directly
40 # instance = aws_instance.cloudcasts_web.id
41 vpc = true
42  
43 lifecycle {
44 prevent_destroy = true
45 }
46  
47 tags = {
48 Name = "cloudcasts-${var.infra_env}-web-address"
49 Role = var.infra_role
50 Project = "cloudcasts.io"
51 Environment = var.infra_env
52 ManagedBy = "terraform"
53 }
54 }
55  
56 resource "aws_eip_association" "eip_assoc" {
57+ count = (var.create_eip) ? 1 : 0
58  
59 instance_id = aws_instance.cloudcasts_web.id
60 allocation_id = aws_eip.cloudcasts_addr[0].id
61 }

File outputs.tf

Lastly, we'll update our outputs to reflect our use of count in the EIP resource.

1# We updated tihs output to use "*" notation
2output "app_eip" {
3 value = aws_eip.cloudcasts_addr.*.public_ip
4}

File cloudcasts.tf

We can then implement our changes into our root module to define our tags and set if we want an EIP:

1module "ec2_app" {
2 source = "./modules/ec2"
3 
4 infra_env = var.infra_env
5 infra_role = "web"
6 instance_size = "t3.small"
7 instance_ami = data.aws_ami.app.id
8 # instance_root_device_size = 12
9 subnets = keys(module.vpc.vpc_public_subnets)
10 # security_groups = [] //
11 security_groups = ["sg-095b0ec176f8fbc14"]
12 tags = {
13 Name = "cloudcasts-${var.infra_env}-web"
14 }
15 create_eip = true
16}
17 
18module "ec2_worker" {
19 source = "./modules/ec2"
20 
21 infra_env = var.infra_env
22 infra_role = "worker"
23 instance_size = "t3.large"
24 instance_ami = data.aws_ami.app.id
25 instance_root_device_size = 20
26 subnets = keys(module.vpc.vpc_private_subnets)
27 # security_groups = [] //
28 security_groups = ["sg-095b0ec176f8fbc14"]
29 tags = {
30 Name = "cloudcasts-${var.infra_env}-worker"
31 }
32 create_eip = false
33}

This allowed us to:

  1. Differentiate our server Name tags ("web" vs "worker")
  2. Only assign an EIP on the web server, which is meant to accept public web traffic

And of course we can run our changes:

1terraform plan -var-file variables.tfvars
2terraform apply -var-file variables.tfvars

Don't miss out

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