Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

@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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

@stgerberding Con fi guration Management Provisioning T ool

Slide 5

Slide 5 text

@stgerberding Mutable Approach Immutable Approach

Slide 6

Slide 6 text

@stgerberding Declarative Approach Procedural Approach

Slide 7

Slide 7 text

@stgerberding Was ist T erraform? … Apply Plan

Slide 8

Slide 8 text

@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

Slide 9

Slide 9 text

@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 ] ]

Slide 10

Slide 10 text

@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

Slide 11

Slide 11 text

@stgerberding Resources Input Variables Output Values Local Values Modules

Slide 12

Slide 12 text

@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

Slide 13

Slide 13 text

@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.

Slide 14

Slide 14 text

@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 "

Slide 15

Slide 15 text

@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

Slide 16

Slide 16 text

@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.

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

@stgerberding Verzeichnisse und Dateien

Slide 19

Slide 19 text

@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

Slide 20

Slide 20 text

@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

Slide 21

Slide 21 text

@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

Slide 22

Slide 22 text

@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

Slide 23

Slide 23 text

@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 …

Slide 24

Slide 24 text

@stgerberding DEMO

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

@stgerberding Ausblick T erraform CDK (beta)

Slide 27

Slide 27 text

@stgerberding Zusammenfassung

Slide 28

Slide 28 text

@stgerberding Vielen Dank für Eure Aufmerksamkeit! @stgerberding 
 http://sandra.gerberding.blog 
 [email protected] 
 https://speakerdeck.com/sandrag