July 06, 2021

 

IaC(infrastructure as code) and Terraform

IaC (Infrastructure as Code) is the process of automating the provisioning & managing of infrastructure components such as compute, network and storage with configuration files rather than a user interface.


images of users, Terraform, cloud providers and resources provisioned


Cloud computing has proven to accelerate service delivery and speed to market with the availability of on-demand access to components that are required to host applications and services. IaC further simplifies this process by defining IT infrastructure as configuration files. When paired with DevOps practices such as version controlled scripting, continuous security, testing and delivery, IaC provides organizations with earlier detection of bugs, greater accuracy and consistency.


There are many tools that facilitate Infrastructure automation such as Terraform, Pulumi, AWS CloudFormation, Chef, Ansible, etc. However Terraform is considered as the most popular and open source de facto tool. There are many advantages of using Terraform such as its human-readable configuration language that enables users to quickly write Terraform code, state files that track resource changes, ability to perform pre-execution checks to validate resource configurations before they are being provisioned, etc.


Terraform Configuration Explained

  • The terraform{} block contains various options for behavior or Terraform such as configuring a backend to store the state of terraform configurations, version of Terraform that should be used, providers required by the current configuration, etc.
  • The provider{} block configures a specific provider to interact with remote systems.
  • The resource{} block defines all the necessary components required for your infrastructure.

Here is a very basic example Terraform configuration file. Let’s call it main.tf

                    
                        terraform {
                            required_providers {
                              aws = {
                                source  = "hashicorp/aws"
                                version = "~> 3.20"
                              }
                            }
                            
                            required_version = ">= 0.14"
                        }
                          
                        provider "aws" {
                            region  = "us-east-1"
                        }
                          
                        resource "aws_s3_bucket" "example" {
                            bucket  = "example-bucket"
                            acl     = "private"
                          
                            tags = {
                              Environment = "Prod"
                            }
                        }
                    
                

How to run Terraform configuration

Prerequisites

  • Terraform should have been installed.
  • An AWS account with IAM user provisioned with sufficient privileges required to perform the necessary actions.

Initialize

Initialize the directory that contains your configuration file (such as main.tf). This downloads and installs the providers that are needed and creates a lock file to record the provider information.

                    
                        $ terraform init

                        Initializing the backend...

                        Initializing provider plugins...
                        - Finding hashicorp/aws versions matching "~> 3.20"…
                        - Installing hashicorp/aws v3.20.0…
                        - Installed hashicorp/aws v3.20.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.
                    
                

Validate

Validates the Terraform configuration file in the directory and checks for syntax.

                    
                        $ terraform validate

                        Success! The configuration is valid.
                    
                

Plan

Creates an execution plan that shows the current state of existing objects and compares it with proposed changes in the configuration file. Here is an example terraform plan to stdout.

                    
                        $ 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_s3_bucket.example will be created
                        + resource "aws_s3_bucket" "example" {
                            + acceleration_status         = (known after apply)
                            + acl                         = "private"
                            + arn                         = (known after apply)
                            + bucket                      = "example-bucket"
                            + bucket_domain_name          = (known after apply)
                            + bucket_regional_domain_name = (known after apply)
                            + force_destroy               = false
                            + hosted_zone_id              = (known after apply)
                            + id                          = (known after apply)
                            + region                      = (known after apply)
                            + request_payer               = (known after apply)
                            + tags                        = {
                                + "Environment" = "Prod"
                                }
                            + website_domain              = (known after apply)
                            + website_endpoint            = (known after apply)

                            + versioning {
                                + enabled    = (known after apply)
                                + mfa_delete = (known after apply)
                                }
                            }

                        Plan: 1 to add, 0 to change, 0 to destroy.

                        ------------------------------------------------------------------------
                    
                

Apply

Executes the actions proposed in the terraform plan. Here is an example terraform apply to stdout.

                    
                        $ terraform apply

                        An execution plan has been generated and is shown below.
                        Resource actions are indicated with the following symbols:
                        + create
                        <= read (data resources)

                        Terraform will perform the following actions:

                        # aws_s3_bucket.example will be created
                        + resource "aws_s3_bucket" "example" {
                            + acceleration_status         = (known after apply)
                            + acl                         = "private"
                            + arn                         = (known after apply)
                            + bucket                      = "example-bucket"
                            + bucket_domain_name          = (known after apply)
                            + bucket_regional_domain_name = (known after apply)
                            + force_destroy               = false
                            + hosted_zone_id              = (known after apply)
                            + id                          = (known after apply)
                            + region                      = (known after apply)
                            + request_payer               = (known after apply)
                            + tags                        = {
                                + "Environment" = "Prod"
                                }
                            + website_domain              = (known after apply)
                            + website_endpoint            = (known after apply)

                            + versioning {
                                + enabled    = (known after apply)
                                + mfa_delete = (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_s3_bucket.example: Creating...
                        aws_s3_bucket.example: Still creating... [10s elapsed]
                        aws_s3_bucket.example: Creation complete after 17s [id=example-bucket]

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

TL;DR IaC (Infrastructure as Code) makes it easy to design, develop and maintain infrastructure through code. However following best practices and standards is as important as automating your infrastructure. To avoid constraints, it is recommended to apply version control, utilize DevOps tooling such as CI/CD, enable quality control to detect bugs or issues before they cascade down, ensure idempotency of your code and use abstract code components for maintainability.


Have questions? Contact Us for more details !