Kirill Zonov

Introduction to Terraform. Terraform + Github

October 22, 2017 | 6 Minute Read

Not a long time ago I had no idea about what is the tool named Terraform. It was just beyond my bounds of interests and problems. But a month ago I changed a company and then had to deal with it. And guys, it’s wow. It’s so amazing thing so I even started liking DevOps job. In a few words, it’s a tool to do infrastructure as a code. As they say on their website “Terraform enables you to safely and predictably create, change, and improve production infrastructure”. In this post, I’ll cover why may you (as a developer or a DevOps) need it and how to get started. Getting started will be not just a hello world, but a real example, you can try right away. You as me can work for a decade with small-to-middle startups, even maybe have devops engineers, even 15+ developers in the team, even probably be a devops guy yourself, but still, know nothing about Terraform. Another thing may be that you work with Chef and it’s absolutely enough for you. The thing is that you just didn’t need it. But if you have 50+ repositories, 40+ developers, tons of lambda functions, EC2 instances, plenty of S3 buckets, you just cannot survive without it. The good part here is that you don’t need to wait until you get to this size and start codifying your infrastructure right now. Worth to mention that Terraform is not the only tool, there are also CloudFormation and Heap. I never tried them, but as I know one real competitor is CloudFormation, but it doesn’t support so many providers as Terraform and afaik, also has nothing to do with so to speak “state” of a provider. If you just starting with it as me - no worries, just use Terraform, it’s great, trust me %) Just to summarize, you should use Terraform in case you don’t want to manually manage repositories/servers/buckets/DNS and other things, but wish code do it for you. Let’s start!

octocat with terraform

Install Terraform on OSX

If you use Homebrew, things go the same as usual:

brew install terraform

It will install the terraform binary for you. Then just to check that it installed properly, try:

$ terraform
Usage: terraform [--version] [--help] <command> [args]

Write basic configuration

Create a file, let it be and add there following code:

resource "github_repository" "terraform-example" {
  name        = "terraform-example"
  description = "My example repo for terraform workshop"
  private = false

The format you use here is a Terraform-specific syntax. You can also use JSON, but they actually don’t recommend it. It’s a bit weird to write such constructions, but after some time they look pretty convenient. Let’s see, what did we write here. Resource means that it’s something you want to create for a remote provider. Provider, in this case, is Github, which as Terraform knows, works with the type you mentioned here - “github_repository”. “terraform-example” is just an internal name you give to your future repository. It won’t be displayed anywhere on Github, you need it just for yourself to work with it in the future (f.e. for access configuring etc.). Name and Description are actually name and description, which will be displayed on Github itself. Private is also a pretty clear option. Next, try to see, is it basically proper syntaxed and what it will try to change on the remote server. Don’t be afraid, this command is only local, it won’t send anything to the outside world.

$ terraform plan
Plugin reinitialization required. Please run "terraform init".
Reason: Could not satisfy plugin requirements.

Wow, it doesn’t work! But don’t worry, it says pretty clear what should you do.

$ terraform init

It will download and install a plugin for Github provider. No issues should be there after it finished - try again terraform plan It will ask you for the organization name. Here is confusion, you cannot manage your personal repos, weeeeeird. So you should first create an organization on Github. And one more weird thing is that you cannot do it via Terraform, so go to Github and do it manually. After you are done - write its name in the input field in your terminal. For me, organization name is RacoonsGroup (yeah, I still own the repo ^_^). Then you’ll need to input your personal Github access token. Be careful, it’s not a password, it’s a token, which you can generate from here. Mark only first block, like here:

Then generate the token, copy it and paste into your terminal prompt. Then you’ll get some response like this:

Terraform will perform the following actions:

  + github_repository.terraform-example
      allow_merge_commit: "true"
      allow_rebase_merge: "true"
      allow_squash_merge: "true"
      description:        "My example repo for terraform workshop"
      name:               "terraform-example"
      private:            "false"

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

It says you that terrafom is going to create one repository with such params. As you may see - there are other options, you can specify in your file. Like allow_squash_merge, f.e. Ok, now it’s time, to become super-serious and run:

$ terraform apply

As you may understand, this operation actually makes a request to the GitHub. You then will need to specify your GitHub options once more, don’t be irritated by this.

github_repository.terraform-example: Creating...
  allow_merge_commit: "" => "true"
  allow_rebase_merge: "" => "true"
  allow_squash_merge: "" => "true"
  default_branch:     "" => ""
  description:        "" => "My example repo for terraform workshop"
  full_name:          "" => ""
  git_clone_url:      "" => ""
  http_clone_url:     "" => ""
  name:               "" => "terraform-example"
  private:            "" => "false"
  ssh_clone_url:      "" => ""
  svn_url:            "" => ""
github_repository.terraform-example: Creation complete after 2s (ID: terraform-example)

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

Yay! This is the result you want! Now you can go to the Github and check that you actually have this repo created. As you see, Terraform is a pretty simple tool, which can give you the power to manage at least Github repositories ;) P.S. If this post worth to share - don’t be afraid to do it :)