User Tools

Site Tools


devops:terraform

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
devops:terraform [2021/05/26 18:36] skipidardevops:terraform [2024/04/03 19:53] (current) skipidar
Line 1: Line 1:
 ===== Terraform ===== ===== Terraform =====
 +
 +===Debugging===
 +
 +
 +<sxh shell>
 +# https://developer.hashicorp.com/terraform/internals/debugging
 +# investigage errors
 +export TF_LOG="TRACE"
 +export TF_LOG_PATH="./terraform.log"
 +</sxh>
 +
 +===Glossary===
 +
 +| Terraform Module |A Terraform module is a set of Terraform configuration files in a single directory.|
 +
 +
  
 Installation Installation
Line 7: Line 23:
 https://www.terraform.io/intro/getting-started/build.html https://www.terraform.io/intro/getting-started/build.html
  
 +Skeleton project
 +https://github.com/skipidar/terraform-skeleton
  
- +== Apply terraform bash script == 
-Apply terraform bash script+
 <sxh bash> <sxh bash>
  
Line 24: Line 41:
  
 #terraform apply #terraform apply
 +</sxh>
  
 +== Upgrade terraform provider ==
  
 +https://developer.hashicorp.com/terraform/tutorials/configuration-language/provider-versioning
 +
 +<sxh bash>
 +
 +terraform init -upgrade
 +
 +Initializing the backend...
 +
 +Initializing provider plugins...
 +- Finding hashicorp/aws versions matching "~> 5.0"...
 +- Installing hashicorp/aws v5.21.0...
 +- Installed hashicorp/aws v5.21.0 (signed by HashiCorp)
 +
 +Terraform has made some changes to the provider dependency selections recorded
 +in the .terraform.lock.hcl file. Review those changes and commit them to your
 +version control system if they represent changes you intended to make.
 +
 +Terraform has been successfully initialized!
 </sxh> </sxh>
  
 +=== Main ===
  
 +Create "**main.tf**"
  
 +<sxh json>
 +terraform {
 +  required_providers {
 +    aws = {
 +      source  = "hashicorp/aws"
 +      version = "~> 3.0"
 +    }
 +  }
 +}
 +
 +provider "aws" {
 +  profile = "default"
 +  region  = format("%s", var.aws_region)
 +}
 +
 +</sxh>
  
 === Variables === === Variables ===
  
-Create "variables.tf"+Create "**variables.tf**"
 <sxh json> <sxh json>
  
-variable "region" { +variable "aws_region" { 
-  description = "Value of the Name tag for the EC2 instance"+  description = "The AWS region to deploy the resources into"
   type = string   type = string
-  default = "eu-west-1"+  default = "eu-central-1"
 } }
 +
 +variable "aws_account_id" {
 +  description = "The AWS account identifier of the project"
 +  type = string
 +  default = "1234567891234"
 +}
 +
 +variable "prefix" {
 +  description = "The resource prefix"
 +  type = string
 +  default = "alf-dev-con1"
 +}
 +
 +
 +locals {
 +  iot_policy = "${var.prefix}-thing2"
 +}
 +
  
  
 </sxh> </sxh>
 +
 +**locals**  defines inner variables.
 +Only here one can combine other variables
  
 Use the variable Use the variable
Line 53: Line 129:
 } }
 </sxh> </sxh>
 +
 +
 +=== Data ===
 +
 +When you define ''data'' blocks Terraform communicates with the **AWS provider** to query AWS and fetch the list of requested resources, mentioned in data-block.
 +
 +<sxh json>
 +
 +</sxh>
 +
 +You can apply filters.
 +
 +<sxh json>
 +
 +# Find the latest available AMI that is tagged with Component = web
 +data "aws_ami" "web" {
 +  filter {
 +    name   = "state"
 +    values = ["available"]
 +  }
 +
 +  filter {
 +    name   = "tag:Component"
 +    values = ["web"]
 +  }
 +
 +  most_recent = true
 +}
 +</sxh>
 +
 +
 +Create **templates.tf**
 +
 +<sxh json>
 +
 +data "template_file" "tf_iot_policy" {
 +  vars = {
 +    aws_region = "${var.aws_region}"
 +    aws_account_id = "${var.aws_account_id}"
 +  }
 +  template = <<EOF
 +{
 +  "Version": "2012-10-17",
 +  "Statement": [
 +    {
 +      "Effect": "Allow",
 +      "Action": [
 +        "iot:Connect",
 +        "iot:Publish",
 +        "iot:Receive",
 +        "iot:Subscribe"
 +      ],
 +      "Resource": "arn:aws:iot:$${aws_region}:$${aws_account_id}:*"
 +    }
 +  ]
 +}
 +EOF
 +}
 +
 +</sxh>
 +
 +Usage
 +<sxh json>
 +resource "aws_iot_policy" "iot_policy" {
 +  name   = "${local.iot_policy}"
 +  policy = "${data.template_file.tf_iot_policy.rendered}"
 +}
 +</sxh>
 +
 +
 +=== Dynamic block ===
 +
 +See https://spacelift.io/blog/terraform-dynamic-blocks
 +
 +To replace the repetitive code as here in a module:
 +<sxh json>
 +resource "azurerm_virtual_network" "dynamic_block" {
 +  name                = "vnet-dynamicblock-example-centralus"
 +  resource_group_name = azurerm_resource_group.dynamic_block.name
 +  location            = azurerm_resource_group.dynamic_block.location
 +  address_space       = ["10.10.0.0/16"]
 +
 +  subnet {
 +    name           = "snet1"
 +    address_prefix = "10.10.1.0/24"
 +  }
 +
 +  subnet {
 +    name           = "snet2"
 +    address_prefix = "10.10.2.0/24"
 +  }
 +
 +  subnet {
 +    name           = "snet3"
 +    address_prefix = "10.10.3.0/24"
 +  }
 +
 +  subnet {
 +    name           = "snet4"
 +    address_prefix = "10.10.4.0/24"
 +  }
 +}
 +</sxh>
 +
 +
 +Use the "dynamic" block
 +
 +<sxh json>
 +resource "azurerm_virtual_network" "dynamic_block" {
 +  name                = "vnet-dynamicblock-example-centralus"
 +  resource_group_name = azurerm_resource_group.dynamic_block.name
 +  location            = azurerm_resource_group.dynamic_block.location
 +  address_space       = ["10.10.0.0/16"]
 +
 +  dynamic "subnet" {
 +    for_each = var.subnets
 +    iterator = item   #optional
 +    content {
 +      name           = item.value.name
 +      address_prefix = item.value.address_prefix
 +    }
 +  }
 +}
 +
 +</sxh>
 +
 +
 +Declare a variable in your module
 +<sxh json>
 +variable "subnets" {
 +  description = "list of values to assign to subnets"
 +  type = list(object({
 +    name           = string
 +    address_prefix = string
 +  }))
 +}
 +</sxh>
 +
 +
 +**USAGE of your module**
 +
 +Assigning values to the variable "subnets", which are taken by the module above.
 +
 +<sxh json>
 +subnets = [
 +  { name = "snet1", address_prefix = "10.10.1.0/24" },
 +  { name = "snet2", address_prefix = "10.10.2.0/24" },
 +  { name = "snet3", address_prefix = "10.10.3.0/24" },
 +  { name = "snet4", address_prefix = "10.10.4.0/24" }
 +]
 +</sxh>
 +
devops/terraform.1622054185.txt.gz · Last modified: by skipidar