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

JAX-2022: YATT: Yet another Terraform talk - Grundlagen und ein bisschen mehr

JAX-2022: YATT: Yet another Terraform talk - Grundlagen und ein bisschen mehr

"Infrastructure as Code" ist heutzutage eine wichtige Komponente, um die Erstellung von Cloud-Umgebungen gut strukturieren, versionieren und verwalten zu können. Als eines der führenden Tools für diesen Zweck gilt HashiCorp Terraform. Ich möchte in meinem Vortrag Grundlagen und Konzepte erklären und einen kleinen Einblick geben, was noch alles machbar ist. Seid gespannt auf die tollen Features, die Terraform außer dem stumpfen Auflisten von Ressourcen noch zu bieten hat.

Sandra Gerberding
PRO

May 04, 2022
Tweet

More Decks by Sandra Gerberding

Other Decks in Programming

Transcript

  1. @stgerberding
    YATT: Yet another T
    erraform talk -
    Grundlagen und ein bisschen mehr ...
    Sandra Gerberding - smartsteuer GmbH

    View Slide

  2. @stgerberding
    Software-Entwicklerin:


    Java Web Anwendungen


    Continuous Integration


    Software-Architektur


    T
    witter:

    @stgerberding


    Blog:

    http://sandra.gerberding.blog


    E-Mail:

    [email protected]


    Speaker Deck:

    https://speakerdeck.com/sandrag
    Sandra Gerberding
    2

    View Slide

  3. @stgerberding
    Was ist Infrastructure as Code (IaC)?
    Network Security Server Storage
    Repository

    View Slide

  4. @stgerberding
    Con
    fi
    guration
    Management
    Provisioning T
    ool

    View Slide

  5. @stgerberding
    Mutable Approach Immutable Approach

    View Slide

  6. @stgerberding
    Declarative Approach Procedural Approach

    View Slide

  7. @stgerberding
    Was ist T
    erraform?

    Apply
    Plan

    View Slide

  8. @stgerberding
    T
    erraform
    Core /CLI
    Provider-Plugins


    Provisioner-Plugins
    Cloud API
    Client Library
    RPC
    Golang
    HTTPS
    https://registry.terraform.io/providers/hashicorp/aws/latest/docs
    Aufbau T
    erraform

    View Slide

  9. @stgerberding
    Syntax T
    erraform
    Argumente
    HCL


    Syntax
    .tf
    Blöcke
    identifier = expression
    type [label]
    {

    Block body [arguments/blocks
    ]

    }
    UTF-8
    Kommentare # einzeili
    g

    // einzeili
    g

    /*…*/ mehrzeilig
    JSON


    Syntax
    .tf.json
    UTF-8
    JSON Property
    JSON Object
    "identifier": "expression"
    "identifier": {
    Object body


    [properties/objects/arrays
    ]

    }
    Kommentare "//": "This …"
    JSON Array
    "identifier": [
    Object body


    [properties/objects/arrays
    ]

    ]

    View Slide

  10. @stgerberding
    terraform
    {

    required_version = ">= 1.0


    required_providers {
    aws =
    {

    source = "hashicorp/aws
    "

    version = "~> 3.56.0
    "

    }

    }

    }

    provider "aws"
    {

    region = "eu-central-1"
    profile = "profile-name
    "

    }

    resource "aws_instance" "project-server"
    {

    ami = "ami-029c64b3c205e6cce
    "

    instance_type = "t4g.micro
    "

    tags =
    {

    Name = "Default Instance"
    }
    }

    HCL T
    erraform Beispiel
    {

    "terraform":
    {

    "required_version": ">= 1.0"
    ,

    "required_providers":
    {

    "aws":
    {

    "source": "hashicorp/aws"
    ,

    "version": "~> 3.56.0
    "

    }

    }

    }
    ,

    "provider":
    {

    "aws":
    {

    "region": "eu-central-1"
    ,

    "profile": "profile-name
    "

    }}
    ,

    "resource":
    {

    "aws_instance":
    {

    "project-server":
    {

    "ami": "ami-029c64b3c205e6cce"
    ,

    "instance_type": "t4g.micro"
    ,

    "tags":
    {

    "Name": "Default Instance
    "

    }

    }

    }

    }

    }
    JSON T
    erraform Beispiel

    View Slide

  11. @stgerberding
    Resources
    Input Variables
    Output Values
    Local Values
    Modules

    View Slide

  12. @stgerberding
    Resources
    resource "aws_instance" "project-server"
    {

    ami = "ami-029c64b3c205e6cce
    "

    instance_type = "t4g.micro
    "

    }
    ..
    foobar = aws_instance.project-server.i
    d

    De
    fi
    nition
    Benutzung

    View Slide

  13. @stgerberding
    Input Variables
    variable "image_id"
    {

    type = strin
    g

    description = "The id of the machine image (AMI) to use for the server.
    "

    default = "ami-029c64b3c205e6cce
    "

    validation
    {

    condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-
    "

    error_message = "The image_id value must be a valid AMI id, starting with \"ami-\".
    "

    }

    }

    De
    fi
    nition
    Benutzung
    foobar = var.image_i
    d

    var.

    View Slide

  14. @stgerberding
    Auswertung-Hierarchie
    Überschreibt
    • Environment Variablen


    • terraform.tfvars Datei


    • terraform.tfvars.json


    • *.auto.tfvars / *.auto.tfvars.json


    • -var / -var-
    fi
    le
    >export TF_VAR_image_id=ami-abc12
    3

    region = "us-east-2
    "

    project = "workshop
    "

    stage = "testing
    "

    image_id = "ami-029c64b3c205e6cce"
    >terraform apply -var-file="testing.tfvars
    "

    >terraform apply -var="image_id=ami-abc123
    "

    View Slide

  15. @stgerberding
    Output Values
    output "ec2_instance_public_ip"
    {

    value = aws_instance.project-server.public_i
    p

    }

    De
    fi
    nition
    module..
    Benutzung
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed
    .

    Outputs
    :

    hostname = terraform.example.co
    m

    private_ip = 10.5.4.8
    2

    public_ip = 94.237.45.22
    1

    foobar = module.my-module.ec2_instance_public_i
    p

    View Slide

  16. @stgerberding
    Local Values
    locals
    {

    /*-------------------------------------------------------------
    -

    RDS (database
    )

    --------------------------------------------------------------*
    /

    rds_instance_allocated_storage = var.stage == "dev" ? 5 : 1
    0

    rds_instance_class = var.stage == "dev" ? "db.t3.micro" : "db.t2.large
    "

    rds_database_name = var.stage == "dev" ? "projectdevdb" : "projectproddb
    "

    rds_database_user_name = "dbuser
    "

    rds_database_backup_retention_period = 1
    4

    rds_database_deletion_protection = var.stage == "dev" ? false : tru
    e

    }

    De
    fi
    nition
    name = local.rds_database_nam
    e

    Benutzung
    local.

    View Slide

  17. @stgerberding
    Modules
    Root Module
    Database Module
    Server Module
    Network Module
    etc. Module
    Output Value
    Input Variables
    Input Variables
    Input Variables
    Input Variables

    View Slide

  18. @stgerberding
    Verzeichnisse und Dateien

    View Slide

  19. @stgerberding
    Modules
    module "network"
    {

    source = "./modules/network"
    base_cidr_block = "10.0.0.0/8
    "

    }

    module "database" {
    source = "./modules/database
    "

    database_name = "myDatabase
    "

    vpc_id = module.network.vpc_i
    d

    subnet_ids = module.network.subnet_ids
    }

    module "consul" {
    source = "hashicorp/consul/aws
    "

    version = "0.0.5"
    servers =
    3

    }
    T
    erraform Registry
    main.tf aus dem Root Verzeichnis
    main.tf aus dem Root Verzeichnis

    View Slide

  20. @stgerberding
    Expressions
    "true" converts to true / "5" converts to 5 // Type conversio
    n

    "Hello, ${var.name}!" // String interpolatio
    n

    [for o in var.list : o.id] // for expressio
    n

    var.list[*].id // splat expressio
    n

    var.dbname != "" ? var.dbname : "default-dbname" // conditional expressio
    n

    View Slide

  21. @stgerberding
    resource_prefix = join("-", [var.project, var.stage]) // project-tes
    t

    substr("hello world", 1, 4) // ell
    o

    concat(["a", ""], ["b", "c"]) // ["a", "", "b", "c"
    ]

    contains(["a", "b", "c"], "a") // tru
    e

    base64decode("SGVsbG8gV29ybGQ=") // Hello Worl
    d

    fileexists("${path.module}/hello.txt")


    Functions

    View Slide

  22. @stgerberding
    Loops
    count -> loop über resources
    resource "aws_instance" "server"
    {

    ami = data.aws_ami.amazon_linux_2_arm64.image_i
    d

    instance_type = "t2.micro
    "

    count = length (var.server_names
    )

    tags =
    {

    name = var.server_names[count.index
    ]

    }

    }
    resource "aws_instance" "server"
    {

    ami = data.aws_ami.amazon_linux_2_arm64.image_i
    d

    instance_type = "t2.micro
    "

    for_each = toset(var.server_names
    )

    tags =
    {

    name = each.valu
    e

    }

    }
    variable "server_names"
    {

    description = "Create server with these names
    "

    type = list(string
    )

    default = ["neo", "trinity", "morpheus"
    ]

    }
    output "upper_server_names"
    {

    value = [for name in var.server_names : upper(name)
    ]

    }
    for_each -> loop über resources


    und inline Blöcke
    for -> loop über lists und maps

    View Slide

  23. @stgerberding
    > terraform init
    > terraform plan
    > terraform apply
    > terraform destroy
    T
    erraform CLI
    https://www.terraform.io/docs/cli/commands/index.html
    > terraform
    > terraform init -help
    T
    erraform CLI
    > terraform output
    > terraform import
    > terraform console
    > terraform validate
    > terraform fmt

    View Slide

  24. @stgerberding
    DEMO

    View Slide

  25. @stgerberding
    T
    erraT
    est
    https://terratest.gruntwork.io/

    View Slide

  26. @stgerberding
    Ausblick T
    erraform CDK (beta)

    View Slide

  27. @stgerberding
    Zusammenfassung

    View Slide

  28. @stgerberding
    Vielen Dank für Eure Aufmerksamkeit!
    @stgerberding

    http://sandra.gerberding.blog

    [email protected]

    https://speakerdeck.com/sandrag

    View Slide