DevOps is the combination of cultural philosophies, practices, and tools that increase an organization’s ability to deliver applications and services at high velocity; evolving and improving products at a faster pace than organizations using traditional software development and infrastructure management processes [1]. It is a software development method, which can bring software development and operational activities together.
The Infrastructure as Code (IaC) is a type of “IT infrastructure provisioning process” where systems are automatically built, managed and provisioned through code execution rather than scripting or a manual process. If your infrastructure is treated as code, you can easily manage your infrastructure just as your application code.
AWS CloudFormation and Terraform are leaders in IaC, which greatly eases the process of provisioning IT resources in the AWS cloud. Among these two, Amazon was the first cloud vendor to offer IaC through CloudFormation, which was launched in 2011. Though AWS CloudFormation is a popular hit in IaC, there was a need to have a cloud independent IaC platform. Terraform has basically fulfilled this task by allowing users to define infrastructure for a variety of cloud vendors (AWS, Azure, Google Cloud, DigitalOcean, etc). It is an open source tool with the features of a simple declarative programming language with the ability to deploy and manage cloud infrastructure using CLI commands.
The below examples illustrate how we can leverage Terraform to execute the following tasks in AWS.
This is where the IAM role creation will be done. This assume_role_policy parameter is a must to be given within the resource block. There are other optional parameters as well, such as name, path, description, etc.
The Terraform script:
resource "aws_iam_role" "ec2_s3_access_role" { name = "s3-role" assume_role_policy = "${file("assumerolepolicy.json")}" }
The resource block above constructs a resource of the stated TYPE (i.e. the initial parameter “aws_iam_role”) and NAME (i.e. the second parameter “ec2_s3_access_role”). The integration of the type and name must be distinctive. Within the block (the { }) is the configuration for the resource.
A resource component in Terraform, constructs a resource, of the given TYPE (first parameter) and NAME (second parameter) when defining a resource. As an example, let’s consider the below script:
resource "aws_iam_instance_profile" "test_profile" { name = "test_profile" roles = ["${aws_iam_role.ec2_s3_access_role.name}"] }
In the above block, aws_iam_instance_profile is the TYPE and test_profile is the NAME. The combination of the type and name must be unique.
The assume_role_policy
parameter in the above resource block allows an entity permission to assume
the role.
The assume role policy:
{ "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }
This is
where we need to define the required policy (i.e. permissions) according to the necessity.
For example, allowing the IAM role to access all the S3 buckets within the region. Providing the
policy is a required parameter. Apart from this, there are other parameters as well, such as arn,
path, id, etc.
The Terraform script:
resource "aws_iam_policy" "policy" { name = "test-policy" description = "A test policy" policy = "${file("policys3bucket.json")}" }
The policy parameter in the above block requires an IAM policy in a JSON format.
What the following
policy does is that it allows the IAM role to access all the S3 buckets and perform any action (i.e.
list buckets, put objects, delete objects, etc.) on those buckets.
The IAM policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "*" } ] }
This is where we’ll be attaching the policy, which we wrote above, to the role we created in the
first step.
The Terraform script:
resource "aws_iam_policy_attachment" "test-attach" { name = "test-attachment" roles = ["${aws_iam_role.ec2_s3_access_role.name}"] policy_arn = "${aws_iam_policy.policy.arn}" }
The aws_iam_policy_attachment
in the above resource block is used to attach a Managed IAM Policy to
user(s), role(s), and/or group(s). But in our case, it was a role. The value for the roles
parameter
has been accessed from the resource block, which we created in step 1.
Value of the role = ${aws_iam_role.ec2_s3_access_role.name}
The same thing applies to the value for policy_arn.
This is the resource that must be used to tag the IAM role to the EC2 instance. When we are creating
the resource block for an EC2 instance, in order for us to assign the role to that instance, it
expects the aws_iam_instance_profile
to be given as a parameter.
The Terraform script:
resource "aws_iam_instance_profile" "test_profile" { name = "test_profile" roles = ["${aws_iam_role.ec2_s3_access_role.name}"] }
The value for the roles parameter has been accessed from the resource block, which we created in step 1.
Here we will be creating a basic free tier EC2 instance and attaching the IAM instance profile,
which we created above in the step 4.
The Terraform script:
resource "aws_instance" "my-test-instance" { ami = "${lookup(var.AmiLinux, var.region)}" instance_type = "t2.micro" iam_instance_profile = "${aws_iam_instance_profile.test_profile.name}" tags { Name = "test-instance" } }
The tags parameter is defined to identify and differentiate the EC2 instance from the others. It simply represents a mapping. The value of ami is being retrieved from the predefined variables, which are defined on a different Terraform script as shown below:
variable "region" { default = "us-east-1" } variable "AmiLinux" { type = "map" default = { us-east-1 = "ami-b73b63a0" # Virginia } description = "have only added one region" }
The following commands should be executed from the terminal, in its respective order, within the directory where the scripts are being saved.
The complete source code is available here for grabs:
www.github.com/Kulasangar/terraform-demo
DevOps Model defined - www.aws.amazon.com/devops/what-is-devops
Terraform official website -www.terraform.io