Terraform

starting from the nugget on linux academy https://linuxacademy.com/cp/nuggets/view/id/124

Terraform works like cloud formation but it can creates in multiple providers not only aws

Editor

terraform-editor

Documentation

My articles about terraform

Tips and Tricks

very nice article, all the website is anyway full of terraform info
https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9#.1aa1e6lk4

Linux installation

get the last download links from here https://www.terraform.io/downloads.html

wget https://releases.hashicorp.com/terraform/0.7.3/terraform_0.7.3_linux_amd64.zip
unzip terraform_0.7.3_linux_amd64.zip
sudo mv terraform /usr/bin/

test if it is ok
[ec2-user@ip-172-29-0-32 ~]$ terraform version
Terraform v0.7.3

Windows Installation

terraform-windows-install

Configuration Documentation Section

In my opinion before starting to write tons of lines code it is a good idea understand some basic terraform code concepts
Terraform Configuration Documentation Section

COMMANDS (CLI)

Terraform Commands (cli)

STATE

https://www.terraform.io/docs/state/index.html
terraform create a state file on your local this obsiosly can be a problem when you work as a team. You need to save your state in a remote repos, there is the atlas commercial solution created by them or you can upload on s3, artifactory, azure ecc

MODULES

Terraform Modules Usage

Commands Summary

terraform plan
terraform apply
terraform show
terraform plan -destroy
terraform destroy

Run Terraform inside a lambda

fantastic idea from this video https://www.youtube.com/watch?v=EbLhfiXVP6Q minute 23
there is a github project here https://github.com/wellcometrust/terraform-lambda
don't forget that lambda run max for 5 minutes

Syntaxt Summary and examples

simple machine

elastic ip and depends on

you can also use a profile inside the ~/.aws/credentials file in linux and refer it

file project.tf (it can be any name because all the .tf files are evaluated)

provider "aws" {
  shared_credentials_file  = "${var.cred-file}"
  profile                  = "${var.profile}"
  region                   = "${var.region}"
}

resource "aws_instance" "example" {
  ami           = "ami-7172b611"
  instance_type = "t2.micro"
}

resource "aws_eip" "ip" {
    instance = "${aws_instance.example.id}"
    depends_on = ["aws_instance.example"]
}

file variables.tf

variable "region" {
  default = "sa-east-1"
}
variable "profile" {
  default = "default"
  description = "AWS credentials profile you want to use"
}
variable "cred-file" {
  default = "/home/vagrant/.aws/credentials"
  description = "the credentials files in your machine you can't use the ~ char"
}

many machines with the same code

#create the ec2 machine
resource "aws_instance" "genericinstances" {
  count = "${var.number}"
  ami = "ami-xxxxxx"
  instance_type = "t2.micro"
  associate_public_ip_address = "false"
  subnet_id = "subnet-xxxxxx"
  private_ip = "172.31.48.${count.index+4}"
  vpc_security_group_ids = ["sg-xxxxxx"]
  key_name = "mypemkey"
  tags {
        Name = "MachineNumber-${count.index}"
  }
}
# associate an elastic ip
resource "aws_eip" "ips" {
  count = "${var.number}"
  instance = "${element(aws_instance.genericinstances.*.id, count.index)}"
}
# define a dns record in it
resource "aws_route53_record" "records" {
   count = "${var.number}"
   zone_id = "xxxxxxxxxxx"
   name = "Mymachinename-${count.index}.mydomain.net"
   type = "A"
   ttl = "10"
   records = ["${element(aws_instance.genericinstances.*.private_ip , count.index)}"]
}

advanced userdata , this can be used inside an ec2 machine or a Launch configuration, the indentation is VERY IMPORTANT

  user_data = <<HEREDOC
     #!/bin/bash
     FILENAME=/home/ec2-user/logstash-config/logstash.conf
     for (( c=1; c<=8; c++ )) do sed -i '$ d' $FILENAME ; done
     echo '   hosts => ["${var.cloudelasticcom}:9243"] ' >> $FILENAME
     echo '   ssl => true ' >> $FILENAME
     echo '   user => "myusername" ' >> $FILENAME
     echo '   password => "mypassword" ' >> $FILENAME
     echo ' } ' >> $FILENAME
     echo '} ' >> $FILENAME
     docker restart logstash
HEREDOC

if you indent correctly you will have this color inside Atom
userdata-terraform.jpg
if you choose a wrong indentation you will have these colors
wrong-terraform-userdata.jpg

windows template with power shell to change the search name

resource "aws_instance" "winmgt" {
  ami           = "${var.win10AmiID}"
  instance_type = "t2.large"
  associate_public_ip_address = "false"
  subnet_id = "${var.Subnet-Destination-id}"
  vpc_security_group_ids = ["${aws_security_group.lab1.id}"]
  key_name = "${var.key_name}"
  tags {
        Name = "${var.EnvIdentifier}-win10"
        OperativeSystem = "Windows 10"
  }
  user_data = " <powershell> Invoke-WmiMethod -class win32_networkadapterconfiguration -name setdnssuffixsearchorder -argumentlist @('${var.region}.compute.internal', '${var.region}.ec2-utilities.amazonaws.com', '${var.EnvIdentifier}'), $null </powershell>"
}

Workaround the sns problem

as it is described in this page https://www.terraform.io/docs/providers/aws/r/sns_topic_subscription.html

Unsupported protocols include the following:

email -- delivery of message via SMTP
email-json -- delivery of JSON-encoded message via SMTP
These are unsupported because the endpoint needs to be authorized and does not generate an ARN until the target email address has been validated. This breaks the Terraform model and as a result are not currently supported.

so to workaround this problem you can do like this
resource "aws_sns_topic" "alarm" {
  name = "alarming"
  provisioner "local-exec" {
    command = "aws sns subscribe --topic-arn ${self.arn} --protocol email --notification-endpoint myemail@mydomain.mine"
  }
}

Run terraform inside codebuild

Filter what is changed and what is not

you can use landscape and install it from here https://github.com/coinbase/terraform-landscape
or a regular expression in atom

^.*\"(.*)\" => \"(\1)\"$\n

replacing what this match with empty
Salvo diversa indicazione, il contenuto di questa pagina è sotto licenza Creative Commons Attribution-ShareAlike 3.0 License