Skip to content

jccguimaraes/infrastructure-as-code

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Infrastructure as Code (IaC)

Abstract

This documentation weights Hashicorp's Terraform against Google Cloud Platform's Cloud Deployment Manager and Amazon Web Service's CloudFormation, providing cons and pros between them.

The goal is to shed some insight on which tool to choose for the right job and ultimately provide guidelines and best practices for each.

Infrastructure as Code is an easy way to declare how we want our infrastructure to look like and keep this changes versioned.

This doesn't mean that appling the configuration will actually provision everything as we wanted.

Table of contents

What is Hashicorp Terraform

"Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions."

This means that we can use the HCL (Hashicorp Configuration Language) independent of the provider and provision the infrastructure following the same language.

The only differences are strictly to how that provider works in terms of resources and what type of parameters those resources accept.

The most simple usage is creating a provider and a vpc resources. This is a side by side comparison.

provider "google" {}                              provider "aws" {
                                                    region  = var.gcp-region
                                                    profile = var.gcp-profile
                                                  }

resource "google_compute_network" "my-vpc" {      resource "aws_vpc" "my-vpc" {
  name                    = "my-vpc-tf"             cidr_block = "10.0.0.0/16"
  auto_create_subnetworks = false                   tags = {
}                                                     Name = "my-vpc-tf"
                                                    }
                                                  }

As seen, the resources needed and parameters of those same resources only depend on the provider specifications.

The developer experience (DX) of what will be created/updated/deleted will be pretty much identical.

Using Terraform does not remove the need to understand how each provider works.

Terraform state

How does Terraform stores and keeps up with the changes that will be apllied? As we seen from GCP and AWS, you get that management state either in the Cloud Development Manager or CloudFormation console / CLI / API.

With Terraform, there is the concept of backend. A configurable property that can be set to a local file, or a remote file, such as s3 or gcs, among others.

This state is not a layer on top of the GCP Cloud Development Manager not of the AWS CloudFormation.

Terraform lock

When an apply / delete action is triggered it attempts to lock the state so it can safely update it without another team member or a CD Pipeline step writes at the same time.

When this action is complete, it unlocks the state.

When a lock is in place and another apply / delete action is triggered, it will fail and will not be queued.

What is GCP Cloud Deployment Manager

"A declarative approach allows the user to specify what the configuration should be and let the system figure out the steps to take."

Configure the gcloud CLI.

gcloud config set core/project my-project-id
gcloud config set compute/region my-region
gcloud config set compute/zone my-zone

gcloud config list

Which should output something close to:

[compute]
region = my-region
zone = my-zone
[core]
account = my-email-account
disable_usage_reporting = True
project = my-project-id

Your active configuration is: [default]
solution type language
Terraform declarative HCL / JSON
Cloud Deployment Manager declarative YAML / JSON
# create deployment preview
gcloud deployment-manager deployments create deployment-demo-1 --config gcp/demo-01.yaml --preview

# update deployment preview
gcloud deployment-manager deployments update deployment-demo-1 --config gcp/demo-01.yaml --preview

# cancel a deployment preview
gcloud deployment-manager deployments cancel-preview deployment-demo-1

# update deployment
gcloud deployment-manager deployments update deployment-demo-1 --config gcp/demo-01.yaml

# delete deployment
gcloud deployment-manager deployments delete deployment-demo-1

What is AWS CloudFormation

solution type language
Terraform declarative HCL / JSON
Cloud Formation declarative YAML / JSON
AWS_PROFILE="MY-PROFILE"

# create stack
aws cloudformation create-stack --stack-name stack-demo-1 --template-body file://demo-01.yaml --profile $AWS_PROFILE

# update stack
aws cloudformation update-stack --stack-name stack-demo-1 --template-body file://demo-01.yaml --profile $AWS_PROFILE

# delete stack
aws cloudformation delete-stack --stack-name stack-demo-1 --profile $AWS_PROFILE

# create a preview change
aws cloudformation create-change-set --stack-name stack-demo-1 --change-set-name preview-changes --template-body file://demo-01.yaml --profile $AWS_PROFILE

# delete a preview change
aws cloudformation delete-change-set --stack-name stack-demo-1 --change-set-name preview-changes --profile $AWS_PROFILE

# view a preview change
aws cloudformation describe-change-set --stack-name stack-demo-1 --change-set-name preview-changes --profile $AWS_PROFILE

Cloud Development Manager versus Terraform

Consider the following example:

provider "google" {}

resource "google_compute_network" "vpc_network" {
  name                    = "my-vpc-tf"
  auto_create_subnetworks = false
}

In order to use Terraform for GCP we create a service account with the following Compute Network Admin role.

For simplicity, download the JSON credentials from the service account and set the following environment variables:

export GOOGLE_CREDENTIALS=serviceaccount-credentials.json
export GOOGLE_PROJECT=project-id
export GOOGLE_REGION=desired-region
export GOOGLE_ZONE=desired-zone

The role has to have the compute.networks.create permission in order for terraform apply to be allowed CRUD operations for this particular type of resource.

Forbidden error example:

Error: Error creating Network: googleapi: Error 403: Required 'compute.networks.create' permission for 'projects/my-project-id/global/networks/my-vpc-tf', forbidden ...

Running the terraform plan will print the following result:

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

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:

  # google_compute_network.vpc_network will be created
  + resource "google_compute_network" "my-vpc" {
      + auto_create_subnetworks         = false
      + delete_default_routes_on_create = false
      + gateway_ipv4                    = (known after apply)
      + id                              = (known after apply)
      + ipv4_range                      = (known after apply)
      + name                            = "my-vpc-tf"
      + project                         = (known after apply)
      + routing_mode                    = (known after apply)
      + self_link                       = (known after apply)
    }

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

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

AWS CloudFormation versus Terraform

Other solutions

Links

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages