This blog is for those who works on scalable cloud infrastructure and automating repetitive tasks.We have tools like Terraform that allow us to turn a little bit of code into something that can plan, deploy, modify, and destroy all of our systems. If we’re able to get it working, we’ll also need to make some changes to each system, such as modifying the disk size and memory, so that our client isn’t wasting money on unused resources.
Instead of modifying an existing system using SSH, which is a mutable process, your systems are rebuilt from a well-reviewed template, validated for correctness, and then deployed if they pass all the required checks. This is what’s called “immutable infrastructure”.
Let’s get started with defining some terms and technology:
- Terraform: a tool used to turn infrastructure development into code.
- AWSCLI: command line utility for managing AWS Cloud resources.
So, why do we want to use Terraform? Because doing things manually is inefficient, sometimes boring, and could also lead to misconfigurations and costly mistakes. We also want to be able to spend more time focusing on more important things, such as the security of our services, our product’s features, and things of that nature.
Setup AWS CLI
###############
[root@localhost ~]# yum install python-pip
[root@localhost ~]# pip install awscli boto3
[root@localhost ~]# export AWS_ACCESS_KEY_ID=<your-key-here>
[root@localhost ~]# export AWS_SECRET_ACCESS_KEY=<your-secret-key-here>
Use terraform to setup AWS infrastructure
#####################################
Create a directory then create a file main.tf
#####################################
[root@localhost ~]# cd AWSterra/
[root@localhost AWSterra]# ls
main.tf
[root@localhost AWSterra]# vim main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-a4dc46db"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags {
Name = "terraform-example"
}
}
The first command to run for a new configuration -- or after checking out an existing configuration from version control -- is terraform init, which initializes various local settings and data that will be used by subsequent commands.
Initialize terraform
################
[root@localhost AWSterra]# terraform init
Initializing provider plugins...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 1.25"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Now plan the execution
#####################
[root@localhost AWSterra]# terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
Now run terraform apply to see how Terraform will apply the configuration to create resources.
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ aws_instance.example
id: <computed>
ami: "ami-a4dc46db"
associate_public_ip_address: <computed>
availability_zone: <computed>
ebs_block_device.#: <computed>
ephemeral_block_device.#: <computed>
get_password_data: "false"
instance_state: <computed>
instance_type: "t2.micro"
ipv6_address_count: <computed>
ipv6_addresses.#: <computed>
key_name: <computed>
network_interface.#: <computed>
network_interface_id: <computed>
password_data: <computed>
placement_group: <computed>
primary_network_interface_id: <computed>
private_dns: <computed>
private_ip: <computed>
public_dns: <computed>
public_ip: <computed>
root_block_device.#: <computed>
security_groups.#: <computed>
source_dest_check: "true"
subnet_id: <computed>
tags.%: "1"
tags.Name: "terraform-example"
tenancy: <computed>
user_data: "c765373c563b260626d113c4a56a46e8a8c5ca33"
volume_tags.%: <computed>
vpc_security_group_ids.#: <computed>
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Now run terraform apply to see how Terraform will apply the configuration to create resources. ###############################################################################[root@localhost AWSterra]# terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ aws_instance.example
id: <computed>
ami: "ami-a4dc46db"
associate_public_ip_address: <computed>
availability_zone: <computed>
ebs_block_device.#: <computed>
ephemeral_block_device.#: <computed>
get_password_data: "false"
instance_state: <computed>
instance_type: "t2.micro"
ipv6_address_count: <computed>
ipv6_addresses.#: <computed>
key_name: <computed>
network_interface.#: <computed>
network_interface_id: <computed>
password_data: <computed>
placement_group: <computed>
primary_network_interface_id: <computed>
private_dns: <computed>
private_ip: <computed>
public_dns: <computed>
public_ip: <computed>
root_block_device.#: <computed>
security_groups.#: <computed>
source_dest_check: "true"
subnet_id: <computed>
tags.%: "1"
tags.Name: "terraform-example"
tenancy: <computed>
user_data: "c765373c563b260626d113c4a56a46e8a8c5ca33"
volume_tags.%: <computed>
vpc_security_group_ids.#: <computed>
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: yes
aws_instance.example: Creating...
ami: "" => "ami-a4dc46db"
associate_public_ip_address: "" => "<computed>"
availability_zone: "" => "<computed>"
ebs_block_device.#: "" => "<computed>"
ephemeral_block_device.#: "" => "<computed>"
get_password_data: "" => "false"
instance_state: "" => "<computed>"
instance_type: "" => "t2.micro"
ipv6_address_count: "" => "<computed>"
ipv6_addresses.#: "" => "<computed>"
key_name: "" => "<computed>"
network_interface.#: "" => "<computed>"
network_interface_id: "" => "<computed>"
password_data: "" => "<computed>"
placement_group: "" => "<computed>"
primary_network_interface_id: "" => "<computed>"
private_dns: "" => "<computed>"
private_ip: "" => "<computed>"
public_dns: "" => "<computed>"
public_ip: "" => "<computed>"
root_block_device.#: "" => "<computed>"
security_groups.#: "" => "<computed>"
source_dest_check: "" => "true"
subnet_id: "" => "<computed>"
tags.%: "" => "1"
tags.Name: "" => "terraform-example"
tenancy: "" => "<computed>"
user_data: "" => "c765373c563b260626d113c4a56a46e8a8c5ca33"
volume_tags.%: "" => "<computed>"
vpc_security_group_ids.#: "" => "<computed>"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
aws_instance.example: Creation complete after 30s (ID: i-0d4605bf2906e7e87)
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Inspect the current state using terraform show:
#######################################
[root@localhost AWSterra]# terraform show
aws_instance.example:
id = i-0d4605bf2906e7e87
ami = ami-a4dc46db
associate_public_ip_address = true
availability_zone = us-east-1a
credit_specification.# = 1
credit_specification.0.cpu_credits = standard
disable_api_termination = false
ebs_block_device.# = 0
ebs_optimized = false
ephemeral_block_device.# = 0
get_password_data = false
iam_instance_profile =
instance_state = running
instance_type = t2.micro
ipv6_addresses.# = 0
key_name =
monitoring = false
network_interface.# = 0
network_interface_id = eni-0f1dc3509e90c14a2
password_data =
placement_group =
primary_network_interface_id = eni-0f1dc3509e90c14a2
private_dns = ip-172-31-92-100.ec2.internal
private_ip = 172.31.92.100
public_dns = ec2-52-55-147-136.compute-1.amazonaws.com
public_ip = 52.55.147.136
root_block_device.# = 1
root_block_device.0.delete_on_termination = true
root_block_device.0.iops = 100
root_block_device.0.volume_id = vol-04c93e404bff05000
root_block_device.0.volume_size = 8
root_block_device.0.volume_type = gp2
security_groups.# = 1
security_groups.3814588639 = default
source_dest_check = true
subnet_id = subnet-74cb135a
tags.% = 1
tags.Name = terraform-example
tenancy = default
user_data = c765373c563b260626d113c4a56a46e8a8c5ca33
volume_tags.% = 0
vpc_security_group_ids.# = 1
vpc_security_group_ids.3395900001 = sg-46ed580d
Now go to your AWS EC2 page to check the instance is running or not
############################################################
Now you can also completely destroy the Terraform-managed infrastructure.
Destroying your infrastructure is a rare event in production environments. But if you're using Terraform to spin up multiple environments such as development, test, QA environments, then destroying is a useful action.
Resources can be destroyed using the terraform destroy command, which is similar to terraform apply but it behaves as if all of the resources have been removed from the configuration.
To destroy managed infrastructure
##################################
[root@localhost AWSterra]# terraform destroy
aws_instance.example: Refreshing state... (ID: i-0d4605bf2906e7e87)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
- aws_instance.example
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.example: Destroying... (ID: i-0d4605bf2906e7e87)
aws_instance.example: Still destroying... (ID: i-0d4605bf2906e7e87, 10s elapsed)
aws_instance.example: Still destroying... (ID: i-0d4605bf2906e7e87, 20s elapsed)
aws_instance.example: Still destroying... (ID: i-0d4605bf2906e7e87, 30s elapsed)
aws_instance.example: Still destroying... (ID: i-0d4605bf2906e7e87, 40s elapsed)
aws_instance.example: Still destroying... (ID: i-0d4605bf2906e7e87, 50s elapsed)
aws_instance.example: Destruction complete after 57s
Destroy complete! Resources: 1 destroyed.


0 Comments