Terraform

Install
https://www.terraform.io/downloads.html

# sudo apt install -y jq
 
URL=$(wget https://checkpoint-api.hashicorp.com/v1/check/terraform -qO- | jq  -r '.current_download_url + "/" + .product + "_" + .current_version + "_linux_amd64.zip"')
wget ${URL} -qP /tmp
unzip -d /tmp /tmp/${URL##*/}
sudo mv /tmp/terraform /usr/local/bin/
# local user installation
#mv /tmp/terraform ~/.local/bin/terraform
 
terraform  version

Debug
https://www.terraform.io/internals/debugging

# enable
export TF_LOG=DEBUG
# disable
export TF_LOG=ERROR
 
TF_LOG=debug OS_DEBUG=1 terraform apply

CLI

# deploy
terraform init
terraform plan
terraform apply -auto-approve
 
# format the Terraform files
terraform fmt
 
# list workspaces
terraform workspace list
 
# destroy
terraform destroy -auto-approve

Install with Ansible

---
- name: Request Terraform API
  uri:
    url: "{{ terraform_api_url }}"
    return_content: yes
  register: content

- set_fact:
    terraform_download_url: "{{ content.json.current_download_url }}"
    terraform_version: "{{ content.json.current_version }}"

- name: Download Terraform {{ terraform_version }}
  unarchive:
    src: "{{ terraform_download_url }}terraform_{{ terraform_version }}_{{ ansible_system|lower}}_amd64.zip"
    remote_src: yes
    dest: /usr/local/bin
    creates: /usr/local/bin/terraform
    mode: 0755
    owner: root
    group: root
>
# ~/.profile
...
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi
 
 
cat <<EOF> /tmp/install-terraform.yml 
#!/usr/bin/env ansible-playbook
 
---
- hosts: localhost
  vars:
    debug: false
  tasks:
    - name: Get latest terraform version
      uri:
        url: https://checkpoint-api.hashicorp.com/v1/check/terraform
        method: GET
      register: uri_result
 
    - debug:
        msg: "{{ uri_result.json | to_nice_json }}"
      when: debug
 
    - set_fact:
        terraform_current_download_url: "{{ uri_result.json.current_download_url }}"
        terraform_current_version: "{{ uri_result.json.current_version }}"
 
    - name: Create "{{ lookup('env','HOME') }}/.local/bin" directory
      file:
        path: "{{ lookup('env','HOME') }}/.local/bin"
        state: directory
 
    - name: Install Terraform {{ terraform_current_version }} to ~/.local/bin/terraform
      unarchive:
        src: "{{ terraform_current_download_url }}/terraform_{{ terraform_current_version }}_{{ ansible_system | lower }}_amd64.zip"
        remote_src: yes
        dest: "{{ lookup('env','HOME') }}/.local/bin"
        mode: 0755
EOF
chmod +x /tmp/install-terraform.yml
/tmp/install-terraform.yml

Providers
https://www.terraform.io/docs/providers/index.html

ansible-playbook /tmp/install-terraform.yml

https://github.com/panticz/ansible/tree/master/roles/terraform
- hosts: localhost
  roles:
    - role: terraform
      tags: terraform

OpenStack module
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs

Output

output "fqdn" {
  value = "${var.environment}-${var.name}.${var.domain}"
}
 
output "vpc" {
  value = {
    vpc_id         = "${module.my_vpc.vpc_id}"
    public_subnet  = "${module.my_vpc.public_subnets_ids}"
    private_subnet = "${module.my_vpc.private_subnets_ids}"
  }  
}

OpenStack security groups
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/compute_secgroup_v2

rule {
    from_port   = 1
    to_port     = 65535
    ip_protocol = "tcp"
    self        = true
}
 
rule {
    from_port   = -1
    to_port     = -1
    ip_protocol = "icmp"
    cidr        = "0.0.0.0/0"
}

for_each
https://stackoverflow.com/questions/58343258/iterate-over-nested-data-with-for-for-each-at-resource-level

provider "openstack" {
  user_name     = var.os_user_name
  tenant_name   = var.os_tenant_name
  password      = var.os_password
  auth_url      = var.os_auth_url
  region        = var.os_region
  endpoint_type = var.os_endpoint_type
  use_octavia   = true
}

Terraform state
https://spacelift.io/blog/terraform-state

functions
https://www.terraform.io/docs/language/functions/toset.html

Zero Downtime Updates with Terraform
https://www.hashicorp.com/blog/zero-downtime-updates-with-terraform

Terraform/
https://www.terraform.io/
https://www.youtube.com/watch?v=TFLQcgZr0no#t=1318.264795
https://releases.hashicorp.com/index.json
https://releases.hashicorp.com/
https://github.com/diodonfrost/terraform-openstack-examples
https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9#1254
https://www.daveperrett.com/articles/2021/08/19/nested-for-each-with-terraform/
https://library.tf/providers/terraform-provider-openstack/openstack/latest/docs/guides/upgrade-guide-version-3
https://blog.gruntwork.io/how-to-create-reusable-infrastructure-with-terraform-modules-25526d65f73d