VERY Quick Start: Terraform

by Jannik Arndt

This post contains the absolut essence from the Terraform Getting Started Guide: https://www.terraform.io/intro/getting-started/install.html

Preparation

brew install terraform

Create aws.tf:

provider "aws" {
  region     = "us-east-1" 
}

resource "aws_instance" "example" {
  ami           = "ami-2757f631" // https://cloud-images.ubuntu.com/locator/ec2/
  instance_type = "t2.micro"
}

AMI = Amazon Machine Images

AWS credentials are stored in environment vars:

export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...

Init

$ terraform init
...
Terraform has been successfully initialized!
...
$ terraform plan -out planfile
  + aws_instance.example
      ami:                          "ami-2757f631"
      associate_public_ip_address:  "<computed>"
...
$ terraform apply planfile
aws_instance.example: Creating...
...
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
aws_instance.example: Still creating... (30s elapsed)
aws_instance.example: Still creating... (40s elapsed)
aws_instance.example: Creation complete (ID: i-00b2e1a29daee4371)
$ terraform show
aws_instance.example:
  id = i-00b2e1a29daee4371
  ami = ami-2757f631
  associate_public_ip_address = true

Change

ami-2757f631 (Ubuntu 16.04 LTS AMI) => ami-b374d5a5 (Ubuntu 16.10 AMI)

In aws.tf:

provider "aws" {
  region     = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = "ami-b374d5a5"
  instance_type = "t2.micro"
}
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
aws_instance.example: Refreshing state... (ID: i-00b2e1a29daee4371)
...
-/+ aws_instance.example (new resource required)
      ami:                          "ami-2757f631" => "ami-b374d5a5" (forces new resource)
      associate_public_ip_address:  "true" => "<computed>"
...
$ terraform apply
aws_instance.example: Refreshing state... (ID: i-00b2e1a29daee4371)
aws_instance.example: Destroying... (ID: i-00b2e1a29daee4371)
...
aws_instance.example: Destruction complete
aws_instance.example: Creating...
  ami:                          "" => "ami-b374d5a5"
  associate_public_ip_address:  "" => "<computed>"
...
aws_instance.example: Creation complete (ID: i-05a8f2e88ae0faace)

Destroy

$ terraform plan -destroy
Refreshing Terraform state in-memory prior to plan...
...
  - aws_instance.example
...
$ terraform destroy
aws_instance.example: Refreshing state... (ID: i-05a8f2e88ae0faace)
...

  - aws_instance.example

Terraform will delete all your managed infrastructure, as shown above. 
There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_instance.example: Destroying... (ID: i-05a8f2e88ae0faace)
aws_instance.example: Destruction complete

Destroy complete! Resources: 1 destroyed.

Assigning an IP to the instance

In aws.tf:

provider "aws" {
  region     = "us-east-1"
}

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

resource "aws_eip" "ip" {
  instance = "${aws_instance.example.id}"
}
$ terraform apply planfile 
aws_instance.example: Creating...
...
aws_instance.example: Creation complete (ID: i-0478b3c5b6a085287)
aws_eip.ip: Creating...
...
aws_eip.ip: Creation complete (ID: eipalloc-6be79a58)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
$ terraform refresh
aws_instance.example: Refreshing state... (ID: i-0478b3c5b6a085287)
aws_eip.ip: Refreshing state... (ID: eipalloc-6be79a58)
$ terraform show
aws_eip.ip:
  id = eipalloc-6be79a58
  association_id = eipassoc-590d9e6c
  domain = vpc
  instance = i-0478b3c5b6a085287
  network_interface = eni-73845aa6
  private_ip = 172.31.17.98
  public_ip = 52.204.255.194
  vpc = true
aws_instance.example:
  id = i-0478b3c5b6a085287
  ami = ami-b374d5a5
  associate_public_ip_address = true

Dependencies

The order in which resources are created is determined by terraforms analysis of (implicit) dependencies. Dependencies can also be defined explicitly, for example:

resource "aws_eip" "ip" {
  instance   = "${aws_instance.example.id}"
  depends_on = ["aws_instance.example"] # <- explicit dependency
}

To view a dependency graph:

$ terraform graph > graph.dot

And open with graphviz: aws_eip.ip aws_instance.example provider.aws [root] meta.count-boundary (count boundary fixup) [root] provider.aws (close) [root] root

Provisioning/Bootstrapping

https://www.terraform.io/docs/provisioners/index.html

Change aws.tf:

resource "aws_instance" "example" {
  ami           = "ami-b374d5a5"
  instance_type = "t2.micro"
  
  # add provisioner
  provisioner "local-exec" {
      command = "echo ${aws_instance.example.public_ip} > ip_address.txt"
  }
}

# add output
output "ip" {
  value = "${aws_eip.ip.public_ip}"
}

Provisioners are only run, when a resource is first created!

$ terraform destroy
...
$ terraform apply
...
Outputs:

  ip = 50.17.232.209

Blog


Storing case classes in a MongoDB database is incredibly easy, once you know how. The same goes for java.time classes such as ZonedDateTime, LocalDate or Duration.

This example uses the official Mongo Scala Driver in version 2.x and the bsoncodec project by Ralph Schaer.



This post contains the absolut essence from the Terraform Getting Started Guide: https://www.terraform.io/intro/getting-started/install.html



Ever wondered where bad code comes from?

“This story is done”

“Shouldn’t someone review it first?”

“Oh, yeah … erm … I’ll do a quick refactoring first and then…”

…when that other person is on holiday!



Some ideas seem great at first but turn out to be incredibly bad in hindsight. I reviewed such an idea today.



I tried to create a single image that contains all the most important git commands:



The Problem

You’re a corporation. Your IT department is old, slow and can’t innovate. Your competitor however can. So you try what every corporation tries: Two-speed IT.



Last week one of our programs failed looking up an airplane by its registration. That’s not a surprise, since ac regs are a horrible identifier. They change all the time. Also there is almost no naming rule at all. Wikipedia states

When painted on the fuselage, the prefix and suffix are usually separated by a dash (for example, YR-BMA). When entered in a flight plan, the dash is omitted (for example, YRBMA). In some countries that use a number suffix rather than letters, like the United States (N), South Korea (HL), and Japan (JA), the prefix and suffix are connected without a dash.



My favourite animal: The Beluga!



TL;DR: You don’t. We eventually gave up on it.

My personal lessons-learned:

  • Pentaho Kettle (or “Community Edition”, CE, i.e. the open-source core) is a great product for one-time data transfer or on-demand data transfer, but not for resilient, scheduled jobs.
  • The “Enterprise Edition” (EE) adds scheduling that doesn’t work reliably, and a very powerless server.
  • Kerberos is a bitch.



Task

You have a denormalized table and want to extract a column into a dimension table.

Caveat

You have to keep the ids.

Extra-Caveat

You use an Oracle database.



I cannot believe that googleing “talend does not work” does not find anything helpful. With this entry I try to fill that void in the internet.



#1

Do not fix your code.

Rather understand why nothing kept you from creating this bug. Make your code so easy that this bug would have been obvious the first time.



Being the IT-guy aka personal first-level-support™ for way more people than I am comfortable with, I have held quite a few mobile phones in my hand and stared into the abyss that is their home screen. The home screen is the modern view into someone’s soul. In a post-privacy-world it is probably one of the most private things we have, since it is utterly worthless to someone who does not interact with it on an hourly basis and has grown to live with whatever way the apps are scattered around the screen.



(via I Love Programming)

Thank goodness, we don’t do production.



Since I bought my personal domain name around 2003, I went through several web-solutions, using static html pages, php pages, a custom designed php cms, finally Wordpress and now, as of yesterday, I am back to static html. The 2016-flavour however, which is another attempt of separation of presentation and content (a concept I highly endorse as a LaTeX user).