How to deploy an EC2 instance with Terraform

Okay so terraform is like ansible but for the cloud. Its probably a bit cooler in what it can do than ansible….but im still still picking it up myself. But ultimately the same thing. If you know ansible you can pick up terraform without too much difficulty.

After a couple of cool writes you should be good to go.

.

Note: Some interesting things to note. If you create a EC2 with terraform and go and delete it manually after. It appears that terraform does not know the states. If you ask terraform to show you the state. As far as it knows the EC2 is all good. Kinda stupid in my opinion…..This is where ansible take the cake, since ansible will actually go and check to see if that VM/EC2 is actually there. But anyway. Its about learning new ways to do things.

.

Terrform Install:

.

 Unzip and install terraform


 
unzip ./terraform_0.14.3_linux_amd64.zip -d /usr/local/bin/


Ex
ampleLog:

[root@nick ~]# unzip ./terraform_0.14.3_linux_amd64.zip -d /usr/local/bin/

Archive: ./terraform_0.14.3_linux_amd64.zip

replace /usr/local/bin/terraform? [y]es, [n]o, [A]ll, [N]one, [r]ename: A

inflating: /usr/local/bin/terraform

 

[root@nick ~]# terraform -v

Terraform v0.14.3


Note: This is to set the environment variable path for terraform if its not set already.

 

 Set the environment variable path

.

 echo “export PATH=”$PATH:/usr/local/bin/”” >> /usr/local/bin/profile_terraform.sh

.

 Now run the script by to set the environment variable path

.

 chmod +x /usr/local/bin/profile_terraform.sh
 /usr/local/bin/profile_terraform.sh

.

.

Setup Terraform to communicate with AWS:

.

 You need to add your aws accesskeyid and secretaccesskey

Note: You can find these inside your aws console under “My Security Credentials” on the top right corner of AWS console.

 

Then Click Access keys (access key ID and secret access key)
Should be listed here, if not create one and download the keys.

 

echo “export AWS_SECRET_ACCESS_KEY=secretyouraccesskey” >> /usr/local/bin/profile_terraform.sh

 echo “export AWS_ACCESS_KEY_ID=accesskeyid” >> /usr/local/bin/profile_terraform.sh

 

 Next you want to create a Provider.tf file. This file tells terraform which aws instance to connect with.

vi provider.tf

#—Content of provider.tf

provider “aws” {

profile = “default”

region = “us-east-1”

}

 

  • Save file

[root@nick]# cat provider.tf

provider “aws” {

profile = “default”

region = “us-east-1”

}

.

 Next you want to create a Create_EC2.tf – This is the file that will create the instance inside your aws instance.

.

.

vi create_ec2.tf

                                   #—Content of create_ec2.tf
                                   resource “aws_instance” “nicktest-1” {
                                   ami = “ami-0fc61db8544a617ed”
                                   instance_type = “t2.micro
                                   }

 

  • Save file
 Now you have to Initialize the terraform by running ‘terraform init. It will check your provider.tf file and based on your cloud provider it will download the modules and plugin.

root@nick bin]# terraform init

.

Initializing the backend…

.

Initializing provider plugins…

– Finding latest version of hashicorp/aws

– Installing hashicorp/aws v3.22.0…

– Installed hashicorp/aws v3.22.0 (signed by HashiCorp)

.

Terraform has created a lock file .terraform.lock.hcl to record the provider

selections it made above. Include this file in your version control repository

so that Terraform can guarantee to make the same selections by default when

you run “terraform init” in the future.

.

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.

[root@nick bin]#

.

 Now let’s run plan. In the planning phase, it is going to show you the detailed plan of execution of service creation code and their sequences. You can to review it and if all the things look good you can go for the next step

.

.

[root@nick bin]# terraform plan

.

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.nicktest-1 will be created

+ resource “aws_instance” “nicktest-1” {

+ ami = “ami-0fc61db8544a617ed”

+ arn = (known after apply)

+ associate_public_ip_address = (known after apply)

+ availability_zone = (known after apply)

+ cpu_core_count = (known after apply)

+ cpu_threads_per_core = (known after apply)

+ get_password_data = false

+ host_id = (known after apply)

+ id = (known after apply)

+ instance_state = (known after apply)

+ instance_type = “t2.micro

+ ipv6_address_count = (known after apply)

+ ipv6_addresses = (known after apply)

+ key_name = (known after apply)

+ outpost_arn = (known after apply)

+ password_data = (known after apply)

+ placement_group = (known after apply)

+ primary_network_interface_id = (known after apply)

+ private_dns = (known after apply)

+ private_ip = (known after apply)

+ public_dns = (known after apply)

+ public_ip = (known after apply)

+ secondary_private_ips = (known after apply)

+ security_groups = (known after apply)

+ source_dest_check = true

+ subnet_id = (known after apply)

+ tenancy = (known after apply)

+ volume_tags = (known after apply)

+ vpc_security_group_ids = (known after apply)

.

+ ebs_block_device {

+ delete_on_termination = (known after apply)

+ device_name = (known after apply)

+ encrypted = (known after apply)

+ iops = (known after apply)

+ kms_key_id = (known after apply)

+ snapshot_id = (known after apply)

+ throughput = (known after apply)

+ volume_id = (known after apply)

+ volume_size = (known after apply)

+ volume_type = (known after apply)

}

.

+ enclave_options {

+ enabled = (known after apply)

}

.

+ ephemeral_block_device {

+ device_name = (known after apply)

+ no_device = (known after apply)

+ virtual_name = (known after apply)

}

.

+ metadata_options {

+ http_endpoint = (known after apply)

+ http_put_response_hop_limit = (known after apply)

+ http_tokens = (known after apply)

}

.

+ network_interface {

+ delete_on_termination = (known after apply)

+ device_index = (known after apply)

+ network_interface_id = (known after apply)

}

.

+ root_block_device {

+ delete_on_termination = (known after apply)

+ device_name = (known after apply)

+ encrypted = (known after apply)

+ iops = (known after apply)

+ kms_key_id = (known after apply)

+ throughput = (known after apply)

+ volume_id = (known after apply)

+ volume_size = (known after apply)

+ volume_type = (known after apply)

}

}

.

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 you can apply the code and it will create the EC2 machine on AWS cloud

.

[root@nick bin]# 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.nicktest-1 will be created

+ resource “aws_instance” “nicktest-1” {

+ ami = “ami-0fc61db8544a617ed”

+ arn = (known after apply)

+ associate_public_ip_address = (known after apply)

+ availability_zone = (known after apply)

+ cpu_core_count = (known after apply)

+ cpu_threads_per_core = (known after apply)

+ get_password_data = false

+ host_id = (known after apply)

+ id = (known after apply)

+ instance_state = (known after apply)

+ instance_type = “t2.micro

+ ipv6_address_count = (known after apply)

+ ipv6_addresses = (known after apply)

+ key_name = (known after apply)

+ outpost_arn = (known after apply)

+ password_data = (known after apply)

+ placement_group = (known after apply)

+ primary_network_interface_id = (known after apply)

+ private_dns = (known after apply)

+ private_ip = (known after apply)

+ public_dns = (known after apply)

+ public_ip = (known after apply)

+ secondary_private_ips = (known after apply)

+ security_groups = (known after apply)

+ source_dest_check = true

+ subnet_id = (known after apply)

+ tenancy = (known after apply)

+ volume_tags = (known after apply)

+ vpc_security_group_ids = (known after apply)

.

+ ebs_block_device {

+ delete_on_termination = (known after apply)

+ device_name = (known after apply)

+ encrypted = (known after apply)

+ iops = (known after apply)

+ kms_key_id = (known after apply)

+ snapshot_id = (known after apply)

+ throughput = (known after apply)

+ volume_id = (known after apply)

+ volume_size = (known after apply)

+ volume_type = (known after apply)

}

.

+ enclave_options {

+ enabled = (known after apply)

}

.

+ ephemeral_block_device {

+ device_name = (known after apply)

+ no_device = (known after apply)

+ virtual_name = (known after apply)

}

.

+ metadata_options {

+ http_endpoint = (known after apply)

+ http_put_response_hop_limit = (known after apply)

+ http_tokens = (known after apply)

}

.

+ network_interface {

+ delete_on_termination = (known after apply)

+ device_index = (known after apply)

+ network_interface_id = (known after apply)

}

.

+ root_block_device {

+ delete_on_termination = (known after apply)

+ device_name = (known after apply)

+ encrypted = (known after apply)

+ iops = (known after apply)

+ kms_key_id = (known after apply)

+ throughput = (known after apply)

+ volume_id = (known after apply)

+ volume_size = (known after apply)

+ volume_type = (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: yes

.

aws_instance.nicktest-1: Creating…

aws_instance.nicktest-1: Still creating… [10s elapsed]

aws_instance.nicktest-1: Still creating… [20s elapsed]

aws_instance.nicktest-1: Creation complete after 27s [id=i-07883b59bcc922e51]

.

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

.

.

.

 You can now do a terraform show and you should see the instance.

.

.

[root@nick bin]# terraform show

# aws_instance.nicktest-1:

resource “aws_instance” “nicktest-1” {

    ami = “ami-0fc61ef7a2b8544a617ed”

    arn = “arn:aws:ec2:us-east-1:047906495434:instance/i-07883b59bcc922e51″

    associate_public_ip_address = true

    availability_zone = “us-east-1e”

    cpu_core_count = 1

    cpu_threads_per_core = 1

    disable_api_termination = false

    ebs_optimized = false

    get_password_data = false

hibernation = false

id = “i-07833343459bcc922e51″

    instance_state = “running”

    instance_type = “t2.micro

ipv6_address_count = 0

ipv6_addresses = []

monitoring = false

    primary_network_interface_id = “eni-08aa9d6ec05f22570”

    private_dns = “ip-172-31-62-225.ec2.internal”

    private_ip = “172.31.62.187

    public_dns = “ec2-3-85-136-118.compute-1.amazonaws.com”

    public_ip = “3.85.136.265

    secondary_private_ips = []

    security_groups = [

“default”,

]

    source_dest_check = true

    subnet_id = “subnet-fce7f5c2”

tenancy = “default”

    volume_tags = {}

    vpc_security_group_ids = [

“sg-2838b90d”,

]

.

    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/xvda

encrypted = false

        iops = 100

throughput = 0

        volume_id = “vol-0d0cfc51b13e65986”

        volume_size = 8

        volume_type = “gp2”

}

}

[root@nick bin]#

Leave a Reply

Your email address will not be published. Required fields are marked *