Validate Terraform code

1dirs -c
2for DIR in $(find ./examples -type d); do
3   pushd $DIR
4   terraform init
5   terraform fmt -check
6   terraform validate
7   popd
8 done

Execute Terraform

 1export DO_PAT="dop_v1_xxxxxxxxxxxxxxxx"
 2doctl auth init --context rkub
 3
 4# inside a dir with a tf file 
 5terraform init
 6terraform validate
 7terraform plan -var "do_token=${DO_PAT}"
 8terraform apply -var "do_token=${DO_PAT}" -auto-approve
 9
10# clean apply
11terraform plan -out=infra.tfplan -var "do_token=${DO_PAT}"
12terraform apply infra.tfplan
13
14# Control
15terraform show terraform.tfstate
16
17# Destroy
18terraform plan -destroy -out=terraform.tfplan -var "do_token=${DO_PAT}"
19terraform apply terraform.tfplan
  • Connect to server getting the ip with terraform command:
1ssh root@$(terraform output -json ip_address_workers | jq -r '.[0]') -i .key

Work with yaml in terraform

Two possibilities:

  • Take Terraform variables and yamlencode to pass it to your config, example:
 1# non-airgap
 2locals {
 3  cloud_init_config = yamlencode({
 4    packages = [
 5      "python3.12"
 6    ]
 7  })
 8}
 9
10# Convert our cloud-init config to userdata
11data "cloudinit_config" "server_config" {
12  gzip          = false
13  base64_encode = false
14  part {
15    content_type = "text/cloud-config"
16    content      = local.cloud_init_config
17  }
18}
  • Or works with templates (allow to use loops and conditions in the template ):
 1# Generate template install-config.yaml
 2resource "local_file" "install-config" {
 3  depends_on = [null_resource.download_and_extract_openshift_install]
 4  content = templatefile("./template/install-config.yaml.tftpl",
 5    {
 6        master_details = local.master_details,
 7        worker_details = local.worker_details,
 8        public_key = tls_private_key.global_key.public_key_openssh,
 9        internal_registry_url = var.internal_registry,
10        registry_ca_certificate = local.registry_ca_certificate,
11
12    }
13  )
14  filename = "${var.okub_install_path}/install-config.yaml"
15}
  • Or work with both:
 1data "template_file" "user_data" {
 2  template = file("${path.module}/${local.cloud_init_version}/cloud_init.cfg.tftpl")
 3  vars = {
 4    os_name    = local.os_name
 5    hostname   = var.hostname
 6    fqdn       = "${var.hostname}.${local.subdomain}"
 7    master_details = indent(8, yamlencode(local.master_details))
 8    worker_details   = indent(8, yamlencode(local.worker_details))
 9    public_key = tls_private_key.global_key.public_key_openssh
10  }
11}

https://plainenglish.io/blog/terraform-yaml

Terraform in airgap

  • So let imagine, you have to package dependencies for below providers:
 1# versions.tf
 2terraform {
 3  required_providers {
 4    ignition = {
 5      source = "community-terraform-providers/ignition"
 6    }
 7    vsphere = {
 8      source = "hashicorp/vsphere"
 9    }
10  }
11  required_version = ">= 0.13"
12}
  • Refine Terraform config to redirect in known path:
1terraform.tfrc
2plugin_cache_dir   = "./.terraform.d/plugin-cache"
  • Then config terraform to look for plugins locally:
1# terraform-airgap.tfrc
2disable_checkpoint = true
3
4provider_installation {
5  filesystem_mirror{
6    path = "../.terraform.d/plugin-cache"
7  }
8}
  • In ansible the logic would be like follow :
 1---
 2# tf providers
 3- name: Push terraform file at root dir
 4  template:
 5    src: "{{ item }}"
 6    dest: "{{ prepare_airgap_deps_path }}/terraform/{{ item }}"
 7    mode: u=rw,g=r,o=r
 8  loop:
 9    - terraform.tfrc
10    - versions.tf
11
12# equivalent to "terraform providers mirror -platform=linux_amd64 .terraform.d/plugin-cache"
13- name: Init terraform to pull providers
14  command: "{{ prepare_airgap_deps_path }}/bin/terraform init -no-color"
15  args:
16    chdir: "{{ prepare_airgap_deps_path }}/terraform"
17  environment: 
18    TF_CLI_CONFIG_FILE: "./terraform.tfrc"
19
20- name: Push terraform file to OCP dir
21  template:
22    src: "{{ item }}"
23    dest: "{{ prepare_airgap_deps_path }}/terraform/ocp/{{ item }}"
24    mode: u=rw,g=r,o=r
25  loop:
26    - terraform-airgap.tfrc
27    - versions.tf
28
29- name: Init terraform to test airgap
30  command: "{{ prepare_airgap_deps_path }}/bin/terraform init -no-color"
31  args:
32    chdir: "{{ prepare_airgap_deps_path }}/terraform/ocp"
33  environment: 
34    TF_CLI_CONFIG_FILE: "./terraform-airgap.tfrc"