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:
-
main.tf
, which defines resources to create -
variables.tf
, which defines variables the module expects to be given values for -
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/ec22cd modules/ec23touch 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 = string13 description = "ec2 web server size"14 default = "t3.small"15}16 17variable instance_ami {18 type = string19 description = "Server image to use"20}21 22variable instance_root_device_size {23 type = number24 description = "Root bock device size in GB"25 default = 1226}
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_role13 Project = "cloudcasts.io"14 Environment = var.infra_env15 ManagedBy = "terraform"16 }17}18 19resource "aws_eip" "cloudcasts_addr" {20 # We're not doing this directly21 # instance = aws_instance.cloudcasts_web.id22 vpc = true23 24 lifecycle {25 prevent_destroy = true26 }27 28 tags = {29 Name = "cloudcasts-${var.infra_env}-web-address"30 Role = var.infra_role31 Project = "cloudcasts.io"32 Environment = var.infra_env33 ManagedBy = "terraform"34 }35}36 37resource "aws_eip_association" "eip_assoc" {38 instance_id = aws_instance.cloudcasts_web.id39 allocation_id = aws_eip.cloudcasts_addr.id40}
File outputs.tf
:
1output "app_eip" {2 value = aws_eip.cloudcasts_addr.public_ip3}4 5output "app_instance" {6 value = aws_instance.cloudcasts_web.id7}
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 = true24 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 official41}42 43variable infra_env {44 type = string45 description = "infrastructure environment"46}47 48variable default_region {49 type = string50 description = "the region this infrastructure is in"51 default = "us-east-2"52}53 54variable instance_size {55 type = string56 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_env65 infra_role = "app"66 instance_size = "t3.small"67 instance_ami = data.aws_ami.app.id68 # instance_root_device_size = 12 # Optional69}70 71module "ec2_worker" {72 source = "./modules/ec2"73 74 infra_env = var.infra_env75 infra_role = "worker"76 instance_size = "t3.large"77 instance_ami = data.aws_ami.app.id78 instance_root_device_size = 5079}
To use our new module, we need to run init
and then we can plan
/apply
:
1terraform init2terraform plan -var-file=variables.tfvars3terraform apply -var-file=variables.tfvars
Note that this change destroys our EIP created in the previous videos and creates new ones!