Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Terraform

Introduction to Terraform

Introduction to Terraform - presented at the Perth Python & Django meetup on March 1 2018. Demo code repo can be found here: https://github.com/jaymickey/terraform-demo

Josh Michielsen

March 01, 2018
Tweet

More Decks by Josh Michielsen

Other Decks in Technology

Transcript

  1. TERRAFORM
    JOSH MICHIELSEN
    1
    Josh Michielsen | jaymickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  2. TERRAFORM IS A TOOL FOR BUILDING, CHANGING, AND
    VERSIONING INFRASTRUCTURE SAFELY AND EFFICIENTLY.
    TERRAFORM CAN MANAGE EXISTING AND POPULAR SERVICE
    PROVIDERS AS WELL AS CUSTOM IN-HOUSE SOLUTIONS
    terraform.io/intro
    WHAT IS TERRAFORM? 2
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  3. WHAT IS TERRAFORM
    QUICK OVERVIEW
    ▸ Developed by HashiCorp.
    ▸ Open Source, written in Go.
    ▸ Command line tool.
    ▸ Declarative programming.
    ▸ HashiCorp Configuration Language (HCL).
    ▸ Domain Specific Language (DSL).
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]
    3

    View Slide

  4. IMPERATIVE VS. DECLARATIVE PROGRAMMING
    IMPERATIVE
    ▸ “A programming paradigm that describes
    computation in terms of statements that
    change a program state.” - Wikipedia1
    ▸ Less wanky: Set of instructions that describe
    how to get to a certain state.
    4
    def makeCoffee(sugars=0, milk=False):
    cup = Cup()
    cup.add_grounds()
    cup.add_water(hot=True)
    if sugars:
    cup.add_sugar(sugars)
    if milk:
    cup.add_milk()
    return cup
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  5. IMPERATIVE VS. DECLARATIVE PROGRAMMING
    DECLARATIVE
    ‣ “A programming paradigm, a style of building
    the structure and elements of computer
    programs, that expresses the logic of a
    computation without describing its control flow.”
    - Wikipedia1
    ‣ Less wanky: Declaring what state you want the
    system to be in, without the details of how to get
    there.
    ‣ Much of the logic is abstracted. Often this is
    presented to the user as a Domain Specific
    Language (DSL).
    5
    coffee = {
    'hot': True,
    'milk': True,
    'sugars': 1
    }
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  6. TERRAFORM BASICS
    WS credentials should
    ion = "${var.region}"
    trieves latest Amazon Linux AMI.
    "aws_ami" "aws_linux_ami" {
    st_recent = true
    lter {
    name = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
    ilter {
    name = "virtualization-type"
    values = ["hvm"]
    }
    dule "web_ec2" {
    source = " ../modules/ec2"
    env = "${var.env}"
    ami_id = "${data.aws_ami.aws_linux_ami.id}"
    count = "${var.count}"
    subnet_id = "${var.subnet_id}"
    module "web_elb" {
    source
    = " ../modules/elb"
    env
    = "${var.env}"
    var.instance_port}"
    "
    6

    View Slide

  7. TERRAFORM BASICS
    PROVIDERS
    Providers are the abstraction layer between you
    and the service you’re attempting to automate.
    These services include IaaS (e.g. OpenStack,
    Digital Ocean), PaaS (e.g. Heroku), SaaS (e.g.
    CloudFlare, GitHub), and full service cloud (e.g.
    AWS, Azure).
    # Provider declaration
    provider "aws" {
    # AWS credentials should be declared as
    environment variables.
    region = “ap-southeast-2“
    }
    7
    main.tf
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  8. TERRAFORM BASICS
    DATA
    Data allows you to query the provider API for
    information that you can then use to configure
    Terraform resources.
    Examples of data includes: AWS AMI, Azure DNS
    zone, GitHub user.
    # Retrieves latest Amazon Linux AMI.
    data "aws_ami" "aws_linux_ami" {
    most_recent = true
    filter {
    name = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
    }
    filter {
    name = "virtualization-type"
    values = ["hvm"]
    }
    }
    8
    main.tf
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  9. TERRAFORM BASICS
    RESOURCES
    Resources are the most important things you’ll
    configure in Terraform. When you declare a
    resource, you are declaring a tangible component
    of your infrastructure.
    Some examples of resources: EC2 instance,
    GitHub repo, CloudFlare DNS record.
    resource "aws_instance" "an_ec2_instance" {
    count = "1"
    ami = "${data.aws_ami.aws_linux_ami.id}"
    instance_type = "t2.micro"
    subnet_id = "subnet-11223344"
    tags = {
    Name = "Some instance"
    Product = "Some product"
    Environment = "Prod"
    Terraform = "true"
    }
    }
    9
    main.tf
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  10. TERRAFORM BASICS
    VARIABLES
    Variables allow you to parameterise your
    Terraform configurations. Allowing you to re-use
    the same code across multiple environments, with
    values passed to the config at runtime.
    Variable declarations can be declared with default
    values, making them optional. Terraform will
    automatically detect the terraform.tfvars file
    if it exists, or you can pass another .tfvars file at
    runtime (e.g. qa.tfvars).
    # Required variables
    variable "env" {}
    variable "count" {}
    # Variables with defaults
    variable "instance_type" {
    default = "t2.micro"
    }
    resource "aws_instance" "an_ec2_instance" {
    count = "${var.count}"
    ami = "${data.aws_ami.aws_linux_ami.id}"
    instance_type = "${var.instance_type}"
    }
    10
    main.tf
    env = "qa"
    count = “2"
    qa.tfvars
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  11. TERRAFORM BASICS
    OUTPUT
    When you use Terraform to create infrastructure, it
    knows everything about those resources. Outputs
    allow you to tell Terraform which information is
    important to you. Terraform will output this
    information after a configuration has been
    applied, or you can query it on-demand using the
    terraform output command.
    resource "aws_instance" "an_ec2_instance" {
    count = "1"
    ami = "${data.aws_ami.aws_linux_ami.id}"
    instance_type = "t2.micro"
    }
    output "instance_ids" {
    value = "${aws_instance.ec2.id}"
    }
    11
    main.tf
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  12. TERRAFORM BASICS
    TFSTATE
    Terraform stores the state of all the resources it
    manages within a text file named
    terraform.tfstate. This file stores all the
    configuration state and metadata of each
    resources being managed within an applied
    configuration.
    Terraform uses this state file to create plans and
    make changes, and will refresh the state with the
    live infrastructure when calling any operation.
    Terraform also supports storing of this state file in
    remote backends such as Amazon S3.
    12
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  13. TERRAFORM
    STRUCTURE
    WS credentials should
    ion = "${var.region}"
    trieves latest Amazon Linux AMI.
    "aws_ami" "aws_linux_ami" {
    st_recent = true
    lter {
    name = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
    ilter {
    name = "virtualization-type"
    values = ["hvm"]
    }
    dule "web_ec2" {
    source = " ../modules/ec2"
    env = "${var.env}"
    ami_id = "${data.aws_ami.aws_linux_ami.id}"
    count = "${var.count}"
    subnet_id = "${var.subnet_id}"
    module "web_elb" {
    source
    = " ../modules/elb"
    env
    = "${var.env}"
    var.instance_port}"
    "
    13

    View Slide

  14. TERRAFORM STRUCTURE
    THE TERRALITH
    ▸ “Monolithic” implementation of
    Terraform configuration.
    ▸ All config in a single file.
    ▸ Limited or no use of variables.
    terraform/
    ├── main.tf
    ├── terraform.tfvars
    14
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  15. TERRAFORM STRUCTURE
    GETTING BETTER
    terraform/
    ├── base/
    │ ├── vpc.tf
    │ ├── network.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    ├── qa/
    │ ├── ec2.tf
    │ ├── cloudwatch.tf
    │ ├── route53.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    └── prod/
    │ ├── ec2.tf
    │ ├── cloudwatch.tf
    │ ├── route53.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    15
    ▸ Environments separated into own their
    own configs.
    ▸ Parameterisation and code reuse.
    ▸ However, hard to manage and lots of
    duplication.
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  16. A BETTER WAY?
    ider decl
    er "aws" {
    S credentials should be declared as environment variabl
    on = "${var.region}"
    rieves latest Amazon Linux AMI.
    "aws_ami" "aws_linux_ami" {
    t_recent = true
    lter {
    name = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
    lter {
    name = "virtualization-type"
    values = ["hvm"]
    ule "web_ec2" {
    source = " ../modules/ec2"
    env = "${var.env}"
    ami_id = "${data.aws_ami.aws_linux_ami.id}"
    count = "${var.count}"
    subnet_id = "${var.subnet_id}"
    odule "web_elb" {
    = " ../modules/elb"

    View Slide

  17. TERRAFORM STRUCTURE
    INTRODUCING MODULES
    terraform/
    ├── base/
    │ ├── main.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    ├── qa/
    │ ├── main.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    ├── prod/
    │ ├── main.tf
    │ ├── variables.tf
    │ ├── terraform.tfvars
    ├── modules/
    │ ├── ec2/
    │ │ ├── main.tf
    │ │ ├── variables.tf
    │ │ ├── output.tf
    │ └── elb/
    │ ├── main.tf
    │ ├── variables.tf
    | ├── output.tf
    17
    ▸ Reusable blocks of code.
    ▸ Highly parameterised.
    ▸ Modelled on your architecture.
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  18. TERRAFORM
    SOME COMMENTS
    ▸ Your Terraform structure should model your service structure.
    ▸ Should I make X a variable: Yes.
    ▸ Segregate, segregate, segregate.
    ▸ Protect your .tfstate file with your life.
    ▸ Use a remote backend, with versioning.
    ▸ Don’t use Terraform for state (DynamoDB, RDS, etc).
    18
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  19. DEMO
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide

  20. THANKS!
    ‣ Official Terraform Docs: https://www.terraform.io/intro/index.html
    ‣ Charity Majors blog posts:
    ‣ https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
    ‣ https://charity.wtf/2016/04/14/scrapbag-of-useful-terraform-tips/
    ‣ Terraform Module Registry: https://registry.terraform.io/
    RESOURCES
    20
    Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

    View Slide