Category Archives: Terraform

Learn Terraform with DevOpsRoles.com. Access detailed guides and tutorials to master infrastructure as code and automate your DevOps workflows using Terraform.

Terraform AWS create VPC: A Comprehensive Step-by-Step Guide

Introduction

How to create AWS VPC using Terraform. In this tutorial, I’m using Terraform AWS create VPC example. Embark on a journey to mastering cloud infrastructure with our detailed tutorial on creating a Virtual Private Cloud (VPC) in AWS using Terraform.

This guide is tailored for DevOps professionals and enthusiasts eager to leverage the scalability and efficiency of AWS. By the end of this tutorial, you will have a clear understanding of how to set up a VPC that aligns perfectly with your organizational needs, ensuring a secure and robust network environment.

Terraform aws create VPC example

The structure folder and files for AWS VPC are as follows

E:\STUDY\TERRAFORM\AWS
└───EC2
│ main.tf
│ outputs.tf
│ variables.tf

Terraform init command is used to initialize a working directory containing Terraform configuration files

terraform init 

The output as the picture below

Use the terraform plan command to create an execution plan.

terraform plan

The output as the picture below

Use terraform apply is to run it.

terraform apply

The output is the picture below

The result on AWS VPC

The content files for Terraform AWS VPC

main.tf file

# dry-run
# terraform plan
# Apply it
# terraform apply
provider "aws" {
    access_key = "${var.aws_access_key}"
	secret_key = "${var.aws_secret_key}"
	region = "${var.region}"
}
# describe the VPC resource.
resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags = {
      Name = "myVPC"
    }
}

variables.tf file

variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "us-west-2"
}

outputs.tf file

output "test" {
    value ="${aws_vpc.myVPC.cidr_block}"
}

Conclusion

Congratulations on successfully creating your AWS VPC using Terraform! This guide aimed to simplify the complexities of cloud networking, providing you with a solid foundation to build upon. As you continue to explore Terraform and AWS, remember that the flexibility and power of these tools can significantly enhance your infrastructure’s reliability and performance.

Keep experimenting and refining your skills to stay ahead in the ever-evolving world of cloud computing. I hope will this your helpful. Thank you for reading the DevopsRoles page!

Terraform build EC2 instance

Introduction

In this tutorial, How to build a simple environment with one EC2 instance base AWS. Terraform build EC2 instance. This time, I created as follows.

  • VPC
  • Internet Gateway
  • Subnet
  • Route Table
  • Security Group
  • EC2

My Environment for Terraform build EC2 instance

  • OS Window
  • Terraform

To install Terraform, By referring to the following.

If you are on Windows, you can install it as follows.

choco install terraform
terraform -help

Create a template file

First of all, Create a subdirectory and a Terraform template file in it. The name of the template file is arbitrary, but the extensions are *.tf

$ mkdir terraform-aws
$ cd terraform-aws
$ touch main.tf

Terraform Provider settings

We use the provided settings AWS. Terraform supports multiple providers.

provider "aws" {
    access_key = "ACCESS_KEY_HERE"
    secret_key = "SECRET_KEY_HERE"
    region = "us-west-2"
}

Credential information

Use of Terraform variables

variable "access_key" {}
variable "secret_key" {}

provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region = "us-west-2"
}

Assigning a value to a variable

There are three ways to assign a value to a variable.

1.Terraform command

$ terraform apply \
-var 'access_key=AXXXXXXXXXXXXXXXXXXXXXX' \
-var 'secret_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

2.Value in the environment variable

$ export TF_VAR_access_key="AXXXXXXXXXXXXXXXXXXXXX"
$ export TF_VAR_secret_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

3.Pass the value in a file

For example, the content terraform.tfvars file.

aws_access_key = "AXXXXXXXXXXXXXXXXXXXXX"
aws_secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

How to set Default value of variable

For example, We can set default values for variables.

variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "us-west-2"
}

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "${var.region}"
}

Provider: AWS –Terraform by HashiCorp

Terraform Resource settings.

In Terraform the resource type is aws_* predefined. Example aws_vpc a VPC, EC2 is aws_instance. Each AWS resource in the format of item name = value. Example the VPC settings.

resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags = {
      Name = "myVPC"
    }
}

Refer other resources

Internet Gateway settings.

resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags {
      Name = "myVPC"
    }
}

resource "aws_internet_gateway" "myGW" {
    vpc_id = "${aws_vpc.myVPC.id}"
}

Dependencies between resources

For example, set up a dependency between the VPC and Internet Gateway.

resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags {
      Name = "myVPC"
    }
}

resource "aws_internet_gateway" "myGW" {
    vpc_id = "${aws_vpc.myVPC.id}"
    depends_on = "${aws_vpc.myVPC}"
}

We mentioned above how to set the default value for a variable. we use of Map as follows

variable "images" {
    default = {
        us-east-1 = "ami-1ecae776"
        us-west-2 = "ami-e7527ed7"
        us-west-1 = "ami-d114f295"
    }
}

The values of variables defined as var.images.us-east-1

Output on the console

output "public ip of aws-test" {
  value = "${aws_instance.aws-test.public_ip}"
}

Terraform build EC2 instance summary

variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "us-west-2"
}

variable "images" {
    default = {
        us-east-1 = "ami-1ecae776"
        us-west-2 = "ami-e7527ed7"
        us-west-1 = "ami-d114f295"
    }
}

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "${var.region}"
}

resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags {
      Name = "myVPC"
    }
}

resource "aws_internet_gateway" "myGW" {
    vpc_id = "${aws_vpc.myVPC.id}"
}

resource "aws_subnet" "public-a" {
    vpc_id = "${aws_vpc.myVPC.id}"
    cidr_block = "10.1.1.0/24"
    availability_zone = "us-west-2a"
}

resource "aws_route_table" "public-route" {
    vpc_id = "${aws_vpc.myVPC.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.myGW.id}"
    }
}

resource "aws_route_table_association" "puclic-a" {
    subnet_id = "${aws_subnet.public-a.id}"
    route_table_id = "${aws_route_table.public-route.id}"
}

resource "aws_security_group" "admin" {
    name = "admin"
    description = "Allow SSH inbound traffic"
    vpc_id = "${aws_vpc.myVPC.id}"
    ingress {
        from_port = 22
        to_port = 22
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

resource "aws_instance" "aws-test" {
    ami = "${var.images.us-west-2}"
    instance_type = "t2.micro"
    key_name = "aws.devopsroles.com"
    vpc_security_group_ids = [
      "${aws_security_group.admin.id}"
    ]
    subnet_id = "${aws_subnet.public-a.id}"
    associate_public_ip_address = "true"
    root_block_device = {
      volume_type = "gp2"
      volume_size = "20"
    }
    ebs_block_device = {
      device_name = "/dev/sdf"
      volume_type = "gp2"
      volume_size = "100"
    }
    tags {
        Name = "aws-test"
    }
}

output "public ip of aws-test" {
  value = "${aws_instance.aws-test.public_ip}"
}

Dry-Run Terraform command

$ terraform plan

terraform plan command will check for syntax errors and parameter errors set in the block, but will not check for the correctness of the parameter values.

Applying a template

Let’s go we apply the template and create a resource on AWS.

$ terraform apply

Use terraform to show the display the content

$ terraform show

Resource changes

  • We add the content in main.tf file.
  • Use terraform plan to check the execution plan. marked with a ” -/ + “. This indicates that the resource will be deleted & recreated as the attribute changes .
  • terraform apply command for creating.

Delete resource

terraform destroy command can delete a set of resources in the template. terraform plan -destroy you can find out the execution plan for resource deletion.

$ terraform plan -destroy
$ terraform destroy

How to split template file

I have settings together in one template file main.tf

You can be divided into 3 files as below

main.tf

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "${var.region}"
}

## Describe the definition of the resource
resource "aws_vpc" "myVPC" {
    cidr_block = "10.1.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "false"
    tags {
      Name = "myVPC"
    }
}

...

variables.tf

variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "us-west-2"
}

variable "images" {
    default = {
        us-east-1 = "ami-1ecae776"
        us-west-2 = "ami-e7527ed7"
        us-west-1 = "ami-d114f295"
    }
}

outputs.tf

output "public ip of aws-test" {
  value = "${aws_instance.aws-test.public_ip}"
}

Conclusion

You have to use Terraform build EC2 instance. I hope will this your helpful. Thank you for reading the DevopsRoles page!

How to install Terraform on Linux

In this tutorial, How to install Terraform on Centos and Ubuntu. Terraform an Open Source tool. It is safely and predictably create, improve and change Infrastructure.

Feature Key

  • Infrastructure as Code
  • Change Automation
  • Execution Plans
  • Resource Graph

Install Terraform on Centos 7

Link download Terraform here. In this tutorial, The current version of Terraform is 0.12.16

$ sudo yum install wget unzip
$ wget https://releases.hashicorp.com/terraform/0.12.16/terraform_0.12.16_linux_amd64.zip
$ sudo unzip ./terraform_0.12.16_linux_amd64.zip -d /usr/local/bin/

Check Terraform has been installed on your system

$ terraform -v

The output terraform version as below

[vagrant@DevopsRoles ~]$ terraform -v
Terraform v0.12.16

Install Terraform on Ubuntu 18.04

$ sudo apt-get install wget unzip
$ wget https://releases.hashicorp.com/terraform/0.12.16/terraform_0.12.16_linux_amd64.zip
$ sudo unzip ./terraform_0.12.16_linux_amd64.zip -d /usr/local/bin/

Check Terraform has been installed on your system

$ terraform -v

Build an EC2 instance with Terraform

Terraform supports various providers. Example create main.tf file.

$ vi main.tf

# The content as below:
provider "aws" {
    access_key = "ACCESS_KEY"
    secret_key = "SECRET_KEY"
    region = "us-east-2a"
}

Resource settings

The syntax is the resource “resource type” “resource name”.

Details: https://www.terraform.io/docs/providers/aws/index.html

Example like this

[vagrant@DevopsRoles terraform]$ cat main.tf  
 provider "aws" {
     access_key = "ACCESS_KEY"
     secret_key = "SECRET_KEY"
     region = "us-east-2"
 }
 resource "aws_instance" "testEC2" {
     ami = "ami-0c64dd618a49aeee8"
     instance_type = "t2.micro"
     #key_name = "AWS-HUUPV"
     vpc_security_group_ids = [   
        "sg-00c448cd3e48ba684" 
       ] 
     associate_public_ip_address = "true" 
     root_block_device {   
        volume_type = "gp2"   
        volume_size = "20" 
     }
 # EBS
     ebs_block_device {
       device_name = "/dev/sdf"
       volume_type = "gp2"
       volume_size = "10"
     }
     tags = {
         Name = "testEC2"
     }
 }
 output "public_ip_of_testEC2" {
   value = "${aws_instance.testEC2.public_ip}"
 }

Note

ami

Access_key and Secure_key. You click IAM –> Roles

Build on AWS

[vagrant@DevopsRoles terraform]$ terraform init
[vagrant@DevopsRoles terraform]$ terraform plan
[vagrant@DevopsRoles terraform]$ terraform apply

The log console terraform as below

[vagrant@DevopsRoles terraform]$ 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.
 
 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.testEC2 will be created
 resource "aws_instance" "testEC2" {
 ami                          = "ami-0c64dd618a49aeee8"
 arn                          = (known after apply)
 associate_public_ip_address  = true
 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)
 network_interface_id         = (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)
 security_groups              = (known after apply)
 source_dest_check            = true
 subnet_id                    = (known after apply)
 tags                         = {
 "Name" = "testEC2"
 }
 tenancy                      = (known after apply)
 volume_tags                  = (known after apply)
 vpc_security_group_ids       = [
 "sg-00c448cd3e48ba684",
 ]
 ebs_block_device {
 delete_on_termination = true
 device_name           = "/dev/sdf"
 encrypted             = (known after apply)
 iops                  = (known after apply)
 kms_key_id            = (known after apply)
 snapshot_id           = (known after apply)
 volume_id             = (known after apply)
 volume_size           = 10
 volume_type           = "gp2"
 }
 ephemeral_block_device {
 device_name  = (known after apply)
 no_device    = (known after apply)
 virtual_name = (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 = true
 encrypted             = (known after apply)
 iops                  = (known after apply)
 kms_key_id            = (known after apply)
 volume_id             = (known after apply)
 volume_size           = 20
 volume_type           = "gp2"
 }
 } 
 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.
 [vagrant@DevopsRoles terraform]$ 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.testEC2 will be created
 resource "aws_instance" "testEC2" {
 ami                          = "ami-0c64dd618a49aeee8"
 arn                          = (known after apply)
 associate_public_ip_address  = true
 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)
 network_interface_id         = (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)
 security_groups              = (known after apply)
 source_dest_check            = true
 subnet_id                    = (known after apply)
 tags                         = {
 "Name" = "testEC2"
 }
 tenancy                      = (known after apply)
 volume_tags                  = (known after apply)
 vpc_security_group_ids       = [
 "sg-00c448cd3e48ba684",
 ]
 ebs_block_device {
 delete_on_termination = true
 device_name           = "/dev/sdf"
 encrypted             = (known after apply)
 iops                  = (known after apply)
 kms_key_id            = (known after apply)
 snapshot_id           = (known after apply)
 volume_id             = (known after apply)
 volume_size           = 10
 volume_type           = "gp2"
 }
 ephemeral_block_device {
 device_name  = (known after apply)
 no_device    = (known after apply)
 virtual_name = (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 = true
 encrypted             = (known after apply)
 iops                  = (known after apply)
 kms_key_id            = (known after apply)
 volume_id             = (known after apply)
 volume_size           = 20
 volume_type           = "gp2"
 }
 } 
 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.testEC2: Creating…
 aws_instance.testEC2: Still creating… [10s elapsed]
 aws_instance.testEC2: Still creating… [20s elapsed]
 aws_instance.testEC2: Still creating… [30s elapsed]
 aws_instance.testEC2: Creation complete after 36s [id=i-0501a62ccf6380761]
 Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
 Outputs:
 public_ip_of_testEC2 = 18.191.123.168

Check on the AWS console!

Have a good nice! Thank you for reading the DevopsRoles page!