@radeksimko
Terraform Goals
● Describe infrastructure as code
● Provision efficiently (get as far as APIs allow at a time)
● Cover the whole lifecycle of the infrastructure
● Provide composability within and across multiple tiers (IaaS, PaaS, SaaS)
@radeksimko
Terraform is NOT solving
● OS-level provisioning
○ Chef
○ Puppet
○ Ansible
○ SaltStack
○ …
● But integrates with these tools
Terminal
@radeksimko
#!/bin/sh
# Renaming DB instance
aws rds create-instance … # new one
aws rds restore-from-snapshot …
aws route53 update-recordset …
aws rds destroy-instance … # old one
Terminal
@radeksimko
#!/bin/sh
# Renaming DB instance
aws rds create-instance … # new one
# wait until state == launched
aws rds restore-from-snapshot …
# wait until restored
aws route53 update-recordset …
# wait until DNS in sync
aws rds destroy-instance … # old one
# wait until instance gone
@radeksimko
Resource Schema
● More or less mapped to API structures
● Allows TF make decisions during the lifecycle
○ Creation
○ Updates
○ Destruction
● Allows TF to present accurate plan ahead of applying it
● Non-updatable fields
@radeksimko
Providers
Amazon Bitbucket CenturyLink Cloud
CloudFlare CloudStack Cobbler
Consul Datadog DigitalOcean
DNSMadeEasy DNSimple Docker
Dyn GitHub Fastly
Google Heroku Librato
Microsoft Azure MySQL OpenStack
Packet PostgreSQL SoftLayer
UltraDNS VMware vSphere and more...
@radeksimko
Providers
Amazon Bitbucket CenturyLink Cloud
CloudFlare CloudStack Cobbler
Consul Datadog DigitalOcean
DNSMadeEasy DNSimple Docker
Dyn GitHub Fastly
Google Heroku Librato
Microsoft Azure MySQL OpenStack
Packet PostgreSQL SoftLayer
UltraDNS VMware vSphere and more...
@radeksimko
Providers
Amazon Bitbucket CenturyLink Cloud
CloudFlare CloudStack Cobbler
Consul Datadog DigitalOcean
DNSMadeEasy DNSimple Docker
Dyn GitHub Fastly
Google Heroku Librato
Microsoft Azure MySQL OpenStack
Packet PostgreSQL SoftLayer
UltraDNS VMware vSphere and more...
@radeksimko
Provider
● Group of resources
● Responsible for validating creds, setting up connection to API(s)
● Works in isolation
○ Terraform core is responsible for relationships between providers
● Is pluggable
○ Binary which talks RPC
○ Can be written in any language
■ But nobody has written helper libraries outside of Go land so far
@radeksimko
Resource
● CR(U)D
○ Create()
○ Read()
○ Update()
○ Delete()
● API specifics
● Responsible for eventually making API calls
● Arguments (e.g. tags to assign to EC2 instance, AMI ID to use)
● Attributes (e.g. instance ID, ...)
@radeksimko
Data Source
● The “R” from resources (CRUD)
● Useful for
○ building on existing infrastructure
○ Keeping configs reusable
● Never modify loaded resource
File
data "aws_availability_zones" "available" {}
# Create 1 subnet per availability zone
resource "aws_subnet" "primary" {
count = "${length(data.aws_availability_zones.available.names)}"
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
...
}
@radeksimko
Existing resources
● Lookups via tags or names
○ Not everything AWS supports tags
○ Not every provider supports tags
○ Tags may not be unique
○ Unique names don’t allow graceful recreation
○ 1 extra lookup API call to get the real unique ID for modify/delete API calls
● Storing unique ID in a state (Terraform)
○ Guaranteed to be unique
○ Provider-agnostic solution
@radeksimko
Worst case scenario
● Duplicate/wrong tag/name
■ Changed wrong resource
■ Destroyed wrong resource
● Drifted/decoupled state
○ Duplicate infrastructure
○ Original (production?) resources intact
@radeksimko
State Mgmt in Terraform
● Part of Remote Backend
○ Remote State
○ Locking
○ Environments
● Many supported backends
○ Consul, etcd
○ Azure Storage, S3, Google Cloud Storage
○ TFE
○ ...