Terraform Documentation: Mithun Software Solutions Bangalore
Terraform Documentation: Mithun Software Solutions Bangalore
Terraform Documentation: Mithun Software Solutions Bangalore
Terraform
Introduction of Terraform
Terraform is an open-source, infrastructure as code software (IaC) tool, maintain the infrastructure
change history using VCS like Git, created by HashiCorp and written in the Go programming
language.
Infrastructure as code is the process of managing infrastructure in a file or files, rather than manually
configuring resources in a user interface (UI).
Here resources are nothing but virtual machines, Elastic IP, Security Groups, Network Interfaces...
Terraform code is written in the HashiCorp Configuration Language (HCL) in files with the extension
.tf
Terraform allows users to use HashiCorp Configuration Language (HCL) to create the files
containing definitions of their desired resources on almost any provider (AWS, GCP, Azure, Digital
Ocean, OpenStack, etc) and automates the creation of those resources at the time of apply.
Advantages of Terraform
Platform Agnostic
State Management
Operator Confidence
It will work for many Cloud Cloud Formation will support only AWS
providers like AWS, Azure, GCP,
Digital Ocean…
Terraform Ansible
Pre-Requisites
1) Any Cloud Provider (AWS, GCP, Azure, Digital Ocean, OpenStack, etc)
2) IAM User credentials (Secret Key and Access Key)
Add the following policies to IAM user if you are using AWS as cloud provider.
AmazonEC2FullAccess
AmazonS3FullAccess
AmazonDynamoDBFullAccess
AmazonRDSFullAccess
CloudWatchFullAccess
IAMFullAccess
Terraform Installation
https://mithuntechnologies-devops.blogspot.com/2020/02/terraform-installation-linux-server.html
https://youtu.be/kxOR-WrK4y8
vim AwsEC2InstanceCreation.tf
The first step in terraform script is typically a provider. Using provide section we can configure our
desired cloud provider.
provider "aws"{
region = "us-east-2"
access_key = "AKIA4UQE3BUQ6GQ3BAFO"
secret_key = "5LAzj2tYFxKf1NNvmvz0Z1USAoEzDAZHlc6R5wHF"
}
This tells Terraform that you are going to be using AWS as your provider and that you want to
deploy your infrastructure into the us-east-2 region.
If you use,
export AWS_ACCESS_KEY_ID="AKIA4UQE3BUQ6GQ3BAEO"
export AWS_SECRET_ACCESS_KEY="5LAzj2tYFxKf1NNvmvz0Z1UASoEzDAZHlc6R5wHF"
Here PROVIDER is the name of a provider (e.g., aws), TYPE is the type of resource to create in that
provider (e.g., instance),
NAME is an identifier you can use throughout the Terraform code to refer to this resource (e.g.,
my_instance),
and CONFIG consists of one or more arguments that are specific to that resource.”
Terraform Commands
terraform init: The terraform init command is used to initialize a working directory containing
Terraform configuration files. This is the first command that should be run after writing a new
Terraform configuration
terraform fmt: The terraform fmt command is used to rewrite Terraform configuration files to a
canonical format and style.
terraform plan: The terraform plan command is used to create an execution plan.
This command is a convenient way to check whether the execution plan for a set of changes
matches your expectations
without making any changes to real resources or to the state.
terraform destroy: The terraform destroy command is used to destroy the Terraform-managed
infrastructure.
terraform show:
terraform graph:
-------------------------------------------------------------------------------------------------------------------------------------
provider "aws"{
region = "ap-south-1"
access_key = "AKIA5KT2FR4HAAZW2BBC"
secret_key = "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"
}
FileName: main.tf
§ Terraform must store state about our managed infrastructure and configuration. This state is
used by Terraform to map real world resources to our configuration, keep track of metadata,
and to improve performance for large infrastructures.
§ This state is stored by default in a local file named terraform.tfstate
count = "5"
provider "aws"{
region = "ap-south-1"
access_key = "AKIA5KT2FR4HAAZW2BBC"
secret_key = "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"
}
Variables
In real-time world, the project has more variables, it is difficult maintain the variables in terraform
script, instead we will put the variables in a separate file called vars.tf as follows.
Example: 4
variable "ami" {
description = "Amazon Machine Image type.."
default = "ami-04169656fea786776"
}
variable "instance_type" {
description = "Instance type, weather t2.micro, t2.medium..."
default = "t2.micro"
}
variable "instances" {
description = "Total number of instances which we are going to create"
default = 2
}
/*
variable "instances"{
}
*/
Note:
1)You can pass N number of variables separated by space like below.
terraform apply -auto-approve -var instances="4" -var instance_type="t2.medium"
2) If you pass the variable value while running "terraform apply" command, it will over with
whatever we have mentioned in vars.tf
Here we are passing the variable value while running the script.
provider "aws" {
region = "ap-south-1"
}
tags = {
Name = "Terraform Server - MSS"
}
}
-------------------------------------------------------------------------------------------------------------------------------------
Example: 5
variable "ami" {
description = "Amazon Machine Image type.."
default = "ami-04169656fea786776"
}
variable "instance_type" {
description = "Instance type, weather t2.micro, t2.medium..."
default = "t2.micro"
}
variable "instances" {
description = "Total number of instances which we are going to create"
default = 2
}
provider "aws" {
region = "ap-south-1"
}
c) /* and */ are start and end delimiters for a comment that might span over multiple lines.
AWS Credentials
The AWS provider offers a various method of providing credentials for authentication.
The following methods are supported.
a) Static credentials
b) Environment variables
c) Shared credentials file
d) EC2 Role
Static credentials
Static credentials can be provided by adding an access_key and secret_key in-line in the AWS
provider block, as follows.
provider "aws" {
region = "ap-south-1"
access_key = "AKIA4UQE3BUQ6GQ3BAEO"
secret_key = "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"
}
Environment variables
export AWS_ACCESS_KEY_ID="accesskey"
export AWS_SECRET_ACCESS_KEY="secretkey"
export AWS_DEFAULT_REGION="ap-south-1"
You can use an AWS credentials file to specify your credentials. The default location is
$HOME/.aws/credentials on Linux and OS X, or "%USERPROFILE%\.aws\credentials" for Windows
users. If we fail to detect credentials inline, or in the environment, terraform will check this location.
You can optionally specify a different location in the configuration by providing the
shared_credentials_file attribute, or in the environment with the
AWS_SHARED_CREDENTIALS_FILE variable. This method also supports a profile configuration
and matching AWS_PROFILE environment variable:
provider "aws" {
region = "ap-south-1"
shared_credentials_file = "/home/mithun/.aws/creds"
profile = "customprofile"
}
Possible Errors:
Error 1
Solution:
Provide Valid Access Key and Secret key.
Error 2
Error 3
user_data
Example: 6
FileName: var.tf
variable "ami"{
description = "AMI Name..."
default = "ami-052c08d70def0ac62"
}
variable "instance_type"{
description = "Instance Type..."
default = "t2.micro"
}
variable "instances" {
description = "Total number of instances which we are going to create"
default = 2
}
FileName: userdata.tf
provider "aws" {
region = "ap-south-1"
}
#!/bin/bash
-------------------------------------------------------------------------------------------------------------------------------------
Outputs
Each output value exported by a module must be declared using an output block as follows.
output "instance_ip_addr" {
value = aws_instance.server.private_ip
}
Example: 7
Filename: output.tf
output "aws_public_ip" {
description = "The Public IP address of the server instance, which it created now."
value = "${aws_instance.AWSEC2Instance.public_ip}"
}
output "aws_private_ip" {
description = "The Private IP address of the server instance, which it created now."
value = "${aws_instance.AWSEC2Instance.private_ip}"
}
-------------------------------------------------------------------------------------------------------------------------------------
Security Groups Creation
A security group acts as a virtual firewall for your instance to control incoming and outgoing
traffic. Inbound rules control the incoming traffic to your instance, and outbound rules control
the outgoing traffic from your instance. ... Security groups are associated with network
interfaces.
Example: 8
FileName: securitygroups.tf
provider "aws" {
region = "ap-south-1"
}
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
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"]
}
tags = {
Name = "SecurityGroupsMSS"
}
}
-------------------------------------------------------------------------------------------------------------------------------------
AWS Identity and Access Management (IAM) enables you to manage access to AWS services and
resources securely. Using IAM, you can create and manage AWS users and groups, and use
permissions to allow and deny their access to AWS resources. IAM is a feature of your AWS
account offered at no additional charge.
Example: 9
FileName: iam.tf
provider "aws" {
region = "ap-south-1"
}
Example: 10
FileName: vars.tf
variable "user_names" {
description = "Create IAM users"
type = list(string)
default = ["mithuntechnologies"]
}
FileName: main.tf
provider "aws" {
region = "ap-south-1"
}
Possible Error:
Solution:
Give the Name without space like AWSIAMUser.
Possible Error:
Solution:
Attach the IAMFullAccess to the user.
------------------------------------------------------------------------------------------------------------------------------------
Simple Storage Service (S3)
Amazon S3 or Amazon Simple Storage Service is a service offered by Amazon Web Services
(AWS) that provides object storage through a web service interface.
Example: 11
FileName: s3bucket.tf
provider "aws" {
region = "ap-southeast-1"
}
lifecycle_rule {
enabled = true
transition {
days = 10
storage_class = "STANDARD_IA"
}
transition {
days = 30
storage_class = "GLACIER"
}
}
tags = {
Name = "S3 Bucket MSS by Terraform"
}
}
Here:
bucket: name of the bucket, if we omit that terraform will assign random bucket name
acl: Default to private (other options public-read and public-read-write)
versioning: Versioning automatically keeps up with different versions of the same object.
Life cycle has enabled here after 10 days move the objects to STANDARD_IA and after 30 days to
GLACIER.
-------------------------------------------------------------------------------------------------------------------------------------
Elastic IP (VPC)
§ An Elastic IP address is a reserved public IP address that you can assign to any EC2
instance in a particular region, until you choose to release it. To allocate an Elastic IP
address to your account in a particular region.
§ When you associate an Elastic IP address with an EC2 instance, it replaces the default
public IP address.
Example:
FileName:
# Provider Block
provider "aws" {
region = "ap-southeast-1"
}
tags = {
Name = "EC2Instance with Elastic IP - MSS"
}
}
//EIp Creation
resource "aws_eip" "msseip" {
-------------------------------------------------------------------------------------------------------------------------------------
Example: 12
FileName: vpc.tf
-------------------------------------------------------------------------------------------------------------------------------------
Data Types
1)Primitive Types
A primitive type is a simple type that isn't made from any other types. All primitive types in Terraform
are represented by a type keyword. The available primitive types are:
2)Complex Types
A complex type is a type that groups multiple values into a single value. Complex types are
represented by type constructors, but several of them also have shorthand keyword versions.
There are two categories of complex types: collection types (for grouping similar values), and
structural types (for grouping potentially dissimilar values).
a)Collection Types
list(...): a sequence of values identified by consecutive whole numbers starting with zero.
The keyword list is a shorthand for list(any), which accepts any element type as long as every
element is the same type. This is for compatibility with older configurations; for new code, we
recommend using the full form.
The keyword map is a shorthand for map(any), which accepts any element type as long as every
element is the same type. This is for compatibility with older configurations; for new code, we
recommend using the full form.
Maps can be made with braces ({}) and colons (:) or equals signs (=): { "foo": "bar", "bar": "baz" }
OR { foo = "bar", bar = "baz" }. Quotes may be omitted on keys, unless the key starts with a number,
in which case quotes are required. Commas are required between key/value pairs for single line
maps. A newline between key/value pairs is sufficient in multi-line maps.
Note: although colons are valid delimiters between keys and values, they are currently ignored
by terraform fmt (whereas terraform fmt will attempt vertically align equals signs).
set(...): a collection of unique values that do not have any secondary identifiers or ordering.
b)Structural Types
A structural type allows multiple values of several distinct types to be grouped together as a single
value. Structural types require a schema as an argument, to specify which types are allowed for
which elements.
object(...): a collection of named attributes that each have their own type.
The schema for object types is { <KEY> = <TYPE>, <KEY> = <TYPE>, ... } — a pair of curly
braces containing a comma-separated series of <KEY> = <TYPE> pairs. Values that match the
object type must contain all of the specified keys, and the value for each key must match its
specified type. (Values with additional keys can still match an object type, but the extra attributes are
discarded during type conversion.)
tuple(...): a sequence of elements identified by consecutive whole numbers starting with zero,
where each element has its own type.
The schema for tuple types is [<TYPE>, <TYPE>, ...] — a pair of square brackets containing a
comma-separated series of types. Values that match the tuple type must have exactly the same
number of elements (no more and no fewer), and the value in each position must match the
specified type for that position.
For example: an object type of object({ name=string, age=number }) would match a value like the
following:
{
name = "John"
age = 52
}
Also, an object type of object({ id=string, cidr_block=string }) would match the object produced by a
reference to an aws_vpc resource, like aws_vpc.example_vpc; although the resource has additional
attributes, they would be discarded during type conversion.
Finally, a tuple type of tuple([string, number, bool]) would match a value like the following:
-------------------------------------------------------------------------------------------------------------------------------------
Resources
https://www.terraform.io/docs/providers/aws/d/ami.html
https://learn.hashicorp.com/terraform/getting-started/intro
https://www.terraform.io/docs/providers/aws/index.html
https://www.terraform.io/intro/index.html