Basic Diagram of AWS Environment to be provisioned

Infrastructure Provisioning using Terraform

There are probably a dozen ways to do the same thing. I chose Terraform to provision my virtual machines in AWS. Why? I’m lazy and didn’t want to keep clicking through the AWS console to spin up three clean VMs. I had to do it about 100 times because I always wanted to start fresh when deploying my cluster. Also, I wanted to destroy (delete) my VMs when I was not using them, so I didn’t have to pay.

I’m using spot instances because they are up to 90% off the normal price. I can get a m3.medium (3.75G RAM) for $0.0067/hr. There are some drawbacks; if amazon wants to raise the price higher than your bid price, they will terminate your instance. Also, you cannot power it off, you can only reboot it.

Installing Terraform is pretty simple. It comes as a compiled binary for your platform. Download it from https://www.terraform.io/downloads.html and follow the instructions. I copied the file to /usr/local/bin/terraform to allow me to run it from any directory on the command line.

Download my git repo with the terraform script to provision three hosts in a security group. https://github.com/magic7s/terraform_aws_spot_instance

Review the README.MD file for additional information on how to customize the script for you.

You will need to have your AWS access_key and secret_key available. I recommend you put it in ~/.aws/credentials and it should look like this:

[default] aws_access_key_id = AAABBBBCCCDDDEEEFFF aws_secret_access_key = ABC123456%$^&*WWWMMMCCC33658

If you installed the AWS CLI you may have already done this.

Once this is done, you can run terraform init .

macbook:terraform_aws_spot_instance brad$ terraform init Initializing provider plugins...

.... [lots of output omitted] Terraform has been successfully initialized! .... [lots of output omitted]

macbook:terraform_aws_spot_instance brad$

Check that the aws region is correct in k8s.tf

variable "aws_region_name" { default = "us-west-2" }

You will need to pre-upload or create your SSH public key to the AWS region you are working in. Here are the instruction to do so. You will need the name of the key pair as listed on the AWS console.

variable "ssh_key_name" {default = "braddown-csicolaptop"}

Review the rest of the k8s.tf file for any changes you may want.

Run terraform plan

macbook:terraform_aws_spot_instance brad$ terraform plan

Refreshing Terraform state in-memory prior to plan...

The refreshed state will be used to calculate this plan, but will not be

persisted to local or remote state storage. data.external.myipaddr: Refreshing state...

data.aws_ami.ubuntu: Refreshing state... ------------------------------------------------------------------------

.... [lots of output omitted] Plan: 7 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform

can't guarantee that exactly these actions will be performed if

"terraform apply" is subsequently run. macbook:terraform_aws_spot_instance brad$

If you get any errors about data.external.myipaddr check that ./myipaddr.sh runs in your local directory. It should produce something like {“ip” : “68.231.198.92” } without error. If that doesn’t work try to comment it out and uncomment the other line.

data "external" "myipaddr" { # Pick one or the other. The second one requires an external script but uses DNS instead of https. #program = ["bash", "-c", "curl -s 'https://api.ipify.org?format=json'"] program = ["bash", "${path.module}/myipaddr.sh"] }

If all is successful run terraform apply and answer yes when prompted.

macbook:terraform_aws_spot_instance brad$ terraform apply

data.external.myipaddr: Refreshing state...

aws_security_group.k8s_sg: Refreshing state... (ID: sg-00dfd8ca76fe4e4f3)

data.aws_ami.ubuntu: Refreshing state...

aws_security_group_rule.allow_all_myip: Refreshing state... (ID: sgrule-2156153638)

aws_security_group_rule.allow_SG_any: Refreshing state... (ID: sgrule-104774467)

aws_security_group_rule.allow_all_egress: Refreshing state... (ID: sgrule-1753581355) .... [lots of output omitted] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: master_ip = 54.218.25.205

worker_ips = [

54.202.109.45,

34.211.115.248

]

macbook:terraform_aws_spot_instance brad$

Congratulations you now have three spot instances, running the latest ubuntu 16.04 ami. The public IP address should output at the bottom. We will need these as we move to Ansible and installing kubernetes.