I started with the EC2 instance that I built here.

I’m building some things out in AWS, so I decided to automate the creation of a Terraform to handle building infrastructure.

I’ll start out with something rudimentary and build it up. The end goal is the ability to create and provision the server from my laptop, pull project code, do some Terraform tasks, then terminate the instance.

This is probably not very typical, but it’s good practice for devops. Code lives somewhere statically, and I only spin up compute when I need it.

In V1, the Terraform code will live on my computer and be copied to the Terraform instance, but I’ll eventually move it to Github.

Installing Terraform

I yaml-ed Terraform’s Ubuntu installation instructions to get this:

---
- name: Install Terraform
  hosts: terraform
  remote_user: ubuntu
  become: yes

  tasks:
    - name: Install Terraform
      block:
        - debug: var=ansible_distribution_release
        - name: Update apt cache
          apt:
            update_cache: yes

        - name: Install required packages
          apt:
            name: "{{ item }}"
            state: present
          loop:
            - gnupg
            - software-properties-common

        - name: Add Hashicorp GPG key
          shell: |
            wget -O- https://apt.releases.hashicorp.com/gpg | \
            gpg --dearmor | \
            sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg            
          args:
            executable: /bin/bash

        - name: Verify GPG key fingerprint
          shell: |
            gpg --no-default-keyring \
            --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
            --fingerprint            
          args:
            executable: /bin/bash

        - name: Add Hashicorp APT repository
          apt_repository:
            repo: 'deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com {{ ansible_distribution_release }} main'
            state: present
            filename: hashicorp

        - name: Update apt cache
          apt:
            update_cache: yes

        - name: Install Terraform
          apt:
            name: terraform
            state: present

One interesting note is that we need the Ubuntu distribution name for the install. We get this from Ansible facts by specifying the ansible_distribution_release.

Rudimentary AWS Provider

I want to manage AWS with this instance, so I needed to setup this server to be able to auth with AWS. Read the Terraform docs on setting up AWS authentication options.

I decided to go with environment variables for now. Here’s how I did this:

  1. I created a role via the AWS console.
  2. I SSHed in to the instance.
  3. I copied access keys for the role and added them to the .bashrc file like this:
export AWS_ACCESS_KEY_ID=XXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXX

If you do this manually, make sure you do . ~/.bashrc so that the env variables take effect!!!

Right now, I’m going to automate this with Ansible’s lineinfile and encrypt with ansible-vault. In the future I will likely assign a service role to the instance as I’d like the full automation experience!

These values need to be encrypted with ansible-vault because committing the repo with the above AWS access keys would let people use your account!

Test It

Once installed, I wanted to test Terraform with AWS.

I created a project directory proj, and added two files to it, providers.tf and main.tf.

providers.tf:

terraform {
    required_providers {
        aws = {
            source = "hashicorp/aws"
        }
    }
}

main.tf:

resource "aws_vpc" "proj_vpc" {
    cidr_block = "10.123.0.0/16"
    enable_dns_hostnames = true
    enable_dns_support = true

    tags = {
        Name = "proj_vpc"
    }
}

Now I can run Terraform!

terraform init # does some terraform stuff and creates config files
terraform plan # will verify that your AWS auth is working

One of my next projects is to automate most of the stuff in the test section above.