Examine the evolution of virtualization technologies from bare metal, virtual machines, and containers and the tradeoffs between them.
Install terraform and configure it to work with AWS
Learn the common terraform commands and how to use them
ā¢Terraform Plan, Apply, Destroy
Use Terraform variables and outputs to improve make our configurations more flexible
Explore HCL language features in Terraform to create more expressive and modular infrastructure code.
Learn to break your code into modules to make it flexible and reuseable
Overview of two primary methods for managing multiple Terraform environments
Techniques for testing and validating Terraform code
Covers how teams generally work with Terraform, including automated deployment with CI/CD
In this lesson, we will demonstrate how to refactor our example web application configuration using Terraform modules. We will also show how to consume a third-party module.
We will start by deploying the Consul module. Consul is a tool by HashiCorp for automating network setup and discovery.
The module is available via the Terraform Registry and helps configure the system with best practices while exposing key input variables.
To deploy the Consul module, navigate to the Consul subdirectory, and create a main.tf
file. Set up the back-end and providers, then reference the Consul module via the GitHub repo where it is stored.
terraform {
# Assumes s3 bucket and dynamo DB table already set up
# See /code/03-basics/aws-backend
backend "s3" {
bucket = "devops-directive-tf-state"
key = "06-organization-and-modules/consul/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locking"
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
############################################################
##
## NOTE: if you are deploying this in your production setup
## follow the instructions in the github repo on how to modify
## deploying with the defaults here as an example of the power
## of modules.
##
## REPO: https://github.com/hashicorp/terraform-aws-consul
##
############################################################
module "consul" {
source = "git@github.com:hashicorp/terraform-aws-consul.git"
}
Run terraform init
and terraform plan
to see that it would provision 52 different resources within the AWS account. These resources include EC2 instances, networking policies, and IAM roles.
By using the Consul module, we can easily configure the complex system without having to manually deploy each resource.
Now let's refactor our example web application configuration using Terraform modules.
To do this, we will break up the configuration into different components:
Move the resource definitions from the main.tf
file to their corresponding .tf
files.
āÆ tree ./06-organization-and-modules
.
āāā README.md
āāā web-app
āĀ Ā āāā main.tf
āāā web-app-module
āāā compute.tf
āāā database.tf
āāā dns.tf
āāā main.tf
āāā networking.tf
āāā outputs.tf
āāā storage.tf
āāā variables.tf
3 directories, 12 files
To consume the module:
main.tf
file in the web-app
directory to consume the web-application-module
moduleterraform {
# Assumes s3 bucket and dynamo DB table already set up
# See /code/03-basics/aws-backend
backend "s3" {
bucket = "devops-directive-tf-state"
key = "06-organization-and-modules/web-app/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locking"
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "db_pass_1" {
description = "password for database #1"
type = string
sensitive = true
}
variable "db_pass_2" {
description = "password for database #2"
type = string
sensitive = true
}
module "web_app_1" {
source = "../web-app-module"
# Input Variables
bucket_prefix = "web-app-1-data"
domain = "devopsdeployed.com"
app_name = "web-app-1"
environment_name = "production"
instance_type = "t2.micro"
create_dns_zone = true
db_name = "webapp1db"
db_user = "foo"
db_pass = var.db_pass_1
}
module "web_app_2" {
source = "../web-app-module"
# Input Variables
bucket_prefix = "web-app-2-data"
domain = "anotherdevopsdeployed.com"
app_name = "web-app-2"
environment_name = "production"
instance_type = "t2.micro"
create_dns_zone = true
db_name = "webapp2db"
db_user = "bar"
db_pass = var.db_pass_2
}
By using these two module blocks, we can easily deploy two copies of the web application with slightly different configurations.
When running terraform apply
, you will be prompted to enter the values for db_pass_1 and db_pass_2. Once the apply is complete, you will have two copies of the web application running across four EC2 instances in AWS.
Finally, run terraform destroy
to clean up the resources created during this lesson.
Now that you have seen how to refactor your Terraform code into different sections, parameterize it with variables, and abstract complexity using modules, you can efficiently provision multiple instances of the web application with different configurations.