Infrastructure as Code with Terraform?
Charles Ranaweera
AWS | Azure | SQL | Fortinet | PMP | ITIL | ISO 27001 | Certified Product Owner
Infrastructure as Code (IaC) tools allow you to manage infrastructure with configuration files rather than through a graphical user interface. IaC allows you to build, change, and manage your infrastructure in a safe, consistent, and repeatable way by defining resource configurations that you can version, reuse, and share.
To deploy infrastructure with Terraform:
Install Terraform (on Windows)
To use Terraform you will need to install it. HashiCorp distributes Terraform as a binary package. You can also install Terraform using popular package managers.
Verify the installation
$ terraform -help
Usage: terraform [-version] [-help] <command> [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
##...
Setting up Docker on Windows
To run Docker on your Windows 10 machine, you must use the Windows Subsystem for Linux (WSL2). Download and install WSL2 before moving on.
Download Docker Desktop for Windows.
After you install Terraform and Docker on your local machine, start Docker Desktop by searching for Docker from your Start Menu and select Docker Desktop in the search results. When the whale icon in the status bar stays steady, Docker Desktop is up-and-running, and is accessible from any terminal window.
For more information on Docker Desktop requirements for Windows, visit the Docker docs
Now create a directory named learn-terraform-docker-container.
$ mkdir learn-terraform-docker-container
This working directory houses the configuration files that you write to describe the infrastructure you want Terraform to create and manage. When you initialize and apply the configuration here, Terraform uses this directory to store required plugins, modules (pre-written configurations), and information about the real infrastructure it created.
Navigate into the working directory.
$ cd learn-terraform-docker-container
In the working directory, create a file called main.tf and paste the following Terraform configuration into it.
Windows
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {
host = "npipe:////.//pipe//docker_engine"
}
resource "docker_image" "nginx" {
name = "nginx"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "tutorial"
ports {
internal = 80
external = 8000
}
}
Initialize the project, which downloads a plugin called a provider that lets Terraform interact with Docker.
$ terraform init
Provision the NGINX server container with apply. When Terraform asks you to confirm type yes and press ENTER.
$ terraform apply
Verify the existence of the NGINX container by visiting localhost:8000 in your web browser or running docker ps to see the container.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
425d5ee58619 e791337790a6 "nginx -g 'daemon of…" 20 seconds ago Up 19 seconds 0.0.0.0:8000->80/tcp tutorial
To stop the container, run terraform destroy.
$ terraform destroy
You've now provisioned and destroyed an NGINX webserver with Terraform.
Build infrastructure in AWS using Terraform
Prerequisites
To follow this tutorial you will need:
To use your IAM credentials to authenticate the Terraform AWS provider, set the AWS_ACCESS_KEY_ID environment variable.
Each Terraform configuration must be in its own working directory. Create a directory for your configuration.
$ mkdir learn-terraform-aws-instance
Change into the directory.
领英推荐
$ cd learn-terraform-aws-instance
Create a file to define your infrastructure. Open main.tf in your text editor, paste in the configuration below, and save the file.
$ notepad main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
Initialize the directory.
$terraform init
Format and validate the configuration
It is recommended to use consistent formatting in all of your configuration files. The terraform fmt command automatically updates configurations in the current directory for readability and consistency.
Format your configuration. Terraform will print out the names of the files it modified, if any. In this case, your configuration file was already formatted correctly, so Terraform won't return any file names.
$ terraform fmt
You can also make sure your configuration is syntactically valid and internally consistent by using the terraform validate command.
Validate your configuration. The example configuration provided above is valid, so Terraform will return a success message.
$ terraform validate
Success! The configuration is valid.
Create infrastructure
Apply the configuration now with the terraform apply command. Terraform will print output similar to what is shown below. Have truncated some of the output to save space.
$ terraform apply
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.app_server will be created
+ resource "aws_instance" "app_server" {
+ ami = "ami-830c94e3"
+ arn = (known after apply)
##...
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Terraform will now pause and wait for your approval before proceeding. If anything in the plan seems incorrect or dangerous, it is safe to abort here before Terraform modifies your infrastructure.
In this case the plan is acceptable, so type yes at the confirmation prompt to proceed. Executing the plan will take a few minutes since Terraform waits for the EC2 instance to become available.
Enter a value: yes
aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Creation complete after 36s [id=i-01e03375ba238b384]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
You have now created infrastructure using Terraform! Visit the EC2 console and find your new EC2 instance.
Note
Per the aws provider block, your instance was created in the us-west-2 region. Ensure that your AWS Console is set to this region.
Inspect the current state using terraform show.
$ terraform show
# aws_instance.app_server:
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-01e03375ba238b384"
associate_public_ip_address = true
availability_zone = "us-west-2c"
cpu_core_count = 1
cpu_threads_per_core = 1
disable_api_termination = false
ebs_optimized = false
get_password_data = false
hibernation = false
id = "i-01e03375ba238b384"
instance_state = "running"
instance_type = "t2.micro"
ipv6_address_count = 0
ipv6_addresses = []
monitoring = false
primary_network_interface_id = "eni-068d850de6a4321b7"
private_dns = "ip-172-31-0-139.us-west-2.compute.internal"
private_ip = "172.31.0.139"
public_dns = "ec2-18-237-201-188.us-west-2.compute.amazonaws.com"
public_ip = "18.237.201.188"
secondary_private_ips = []
security_groups = [
"default",
]
source_dest_check = true
subnet_id = "subnet-31855d6c"
tags = {
"Name" = "ExampleAppServerInstance"
}
tenancy = "default"
vpc_security_group_ids = [
"sg-0edc8a5a",
]
credit_specification {
cpu_credits = "standard"
}
enclave_options {
enabled = false
}
metadata_options {
http_endpoint = "enabled"
http_put_response_hop_limit = 1
http_tokens = "optional"
}
root_block_device {
delete_on_termination = true
device_name = "/dev/sda1"
encrypted = false
iops = 0
tags = {}
throughput = 0
volume_id = "vol-031d56cc45ea4a245"
volume_size = 8
volume_type = "standard"
}
}
Destroy what you created above
The terraform destroy command terminates resources managed by your Terraform project. This command is the inverse of terraform apply in that it terminates all the resources specified in your Terraform state. It does not destroy resources running elsewhere that are not managed by the current Terraform project.
Destroy the resources you created.
$ terraform destroy
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.app_server will be destroyed
- resource "aws_instance" "app_server" {
- ami = "ami-08d70e59c07c61a3a" -> null
- arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-0fd4a35969bd21710" -> null
##...
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
The - prefix indicates that the instance will be destroyed. As with apply, Terraform shows its execution plan and waits for approval before making any changes.
Answer yes to execute this plan and destroy the infrastructure.
Enter a value: yes
aws_instance.app_server: Destroying... [id=i-0fd4a35969bd21710]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 30s elapsed]
aws_instance.app_server: Destruction complete after 31s
Destroy complete! Resources: 1 destroyed.
Just like with apply, Terraform determines the order to destroy your resources. In this case, Terraform identified a single instance with no other dependencies, so it destroyed the instance. In more complicated cases with multiple resources, Terraform will destroy them in a suitable order to respect dependencies.
?? Found this helpful? Share your thoughts below or DM me if you like to connect and explore the limitless possibilities of cloud automation together!
Sources harshicorp.com
updated on 11/02/2025 by Charles Ranaweera
#AWS #Terraform #CloudAutomation #DevOps #InfrastructureAsCode #CloudComputing