An EC2 Modules

We see exactly what modules are by creating our first one!

We create a new modules directory and some of its base files:

Creating a Module

We created a modules directory in the last video, and now we'll create a new one named ec2.

A module usually contains at least 3 files:

  1. main.tf, which defines resources to create
  2. variables.tf, which defines variables the module expects to be given values for
  3. outputs.tf, which defines what data the modules provides for other terraform configuration to read

We'll see what that all means going forward.

We create those files for the ec2 server:

1mkdir -p modules/ec2
2cd modules/ec2
3touch variables.tf main.tf outputs.tf

Then we go about filling in those 3 files.

File variables.tf:

1variable infra_env {
2 type = string
3 description = "infrastructure environment"
4}
5 
6variable infra_role {
7 type = string
8 description = "infrastructure purpose"
9}
10 
11variable instance_size {
12 type = string
13 description = "ec2 web server size"
14 default = "t3.small"
15}
16 
17variable instance_ami {
18 type = string
19 description = "Server image to use"
20}
21 
22variable instance_root_device_size {
23 type = number
24 description = "Root bock device size in GB"
25 default = 12
26}

File main.tf:

1resource "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 tags = {
11 Name = "cloudcasts-${var.infra_env}-web"
12 Role = var.infra_role
13 Project = "cloudcasts.io"
14 Environment = var.infra_env
15 ManagedBy = "terraform"
16 }
17}
18 
19resource "aws_eip" "cloudcasts_addr" {
20 # We're not doing this directly
21 # instance = aws_instance.cloudcasts_web.id
22 vpc = true
23 
24 lifecycle {
25 prevent_destroy = true
26 }
27 
28 tags = {
29 Name = "cloudcasts-${var.infra_env}-web-address"
30 Role = var.infra_role
31 Project = "cloudcasts.io"
32 Environment = var.infra_env
33 ManagedBy = "terraform"
34 }
35}
36 
37resource "aws_eip_association" "eip_assoc" {
38 instance_id = aws_instance.cloudcasts_web.id
39 allocation_id = aws_eip.cloudcasts_addr.id
40}

File outputs.tf:

1output "app_eip" {
2 value = aws_eip.cloudcasts_addr.public_ip
3}
4 
5output "app_instance" {
6 value = aws_instance.cloudcasts_web.id
7}

Modules are Reusable!

We can edit our "root module" file cloudcasts.tf and use our module more than once:

1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 3.0"
6 }
7 }
8 
9 backend "s3" {
10 bucket = "terraform-course-cloudcasts"
11 key = "cloudcasts/terraform.tfstate"
12 region = "us-east-2"
13 profile = "cloudcasts"
14 }
15}
16 
17provider "aws" {
18 profile = "cloudcasts"
19 region = "us-east-2"
20}
21 
22data "aws_ami" "ubuntu" {
23 most_recent = true
24 
25 filter {
26 name = "name"
27 values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
28 }
29 
30 filter {
31 name = "virtualization-type"
32 values = ["hvm"]
33 }
34 
35 filter {
36 name = "architecture"
37 values = ["x86_64"]
38 }
39 
40 owners = ["099720109477"] # Canonical official
41}
42 
43variable infra_env {
44 type = string
45 description = "infrastructure environment"
46}
47 
48variable default_region {
49 type = string
50 description = "the region this infrastructure is in"
51 default = "us-east-2"
52}
53 
54variable instance_size {
55 type = string
56 description = "ec2 web server size"
57 default = "t3.small"
58}
59 
60 
61module "ec2_app" {
62 source = "./modules/ec2"
63 
64 infra_env = var.infra_env
65 infra_role = "app"
66 instance_size = "t3.small"
67 instance_ami = data.aws_ami.app.id
68 # instance_root_device_size = 12 # Optional
69}
70 
71module "ec2_worker" {
72 source = "./modules/ec2"
73 
74 infra_env = var.infra_env
75 infra_role = "worker"
76 instance_size = "t3.large"
77 instance_ami = data.aws_ami.app.id
78 instance_root_device_size = 50
79}

To use our new module, we need to run init and then we can plan/apply:

1terraform init
2terraform plan -var-file=variables.tfvars
3terraform apply -var-file=variables.tfvars

Note that this change destroys our EIP created in the previous videos and creates new ones!

Don't miss out

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