ansible / terraform-provider-ansible

community terraform provider for ansible
https://registry.terraform.io/providers/ansible/ansible/latest
GNU General Public License v3.0
201 stars 45 forks source link

Support more complex variables types #128

Open raspbeguy opened 5 months ago

raspbeguy commented 5 months ago

Hello,

When using a ansible_host or ansible_group resource, I wish I could set variables with complex types instead of only strings.

For instances I would like to set a list or a map (those types are supported in static yaml variables files in Ansible). For example I wish I could have this:

resource "ansible_host" "starship" {
  name = "destroyer"
  variables = {
    components = [ "engine", "weapons" ]
  }
]

which would be equivalent to this static Ansible config:

---
components:
  - engine
  - weapons
sikha-root commented 4 months ago

For a workaround, JSON encoding and decoding should work for several use cases, but requires setting two variables.

resource "ansible_host" "example" {
  name   = "example"
  variables = {
    peers_json = jsonencode({
      "host01" = {
        abc = "xyz"
      }
    })
  }
}
---
- name: some play
  hosts: example
  roles:
    - hjkl.hjkl
  vars:
    peers: "{{ peers_json | from_json }}"
EdwardCooke commented 2 months ago

Without doing 2 variables, so you can use other playbooks easily, you could output to a second inventory file.

locals {
  special_config = {
    "kubernetes" = {
      "vars" = {
        "kubernetes_init_skip_phases" = [ "kube-proxy" ]
      }
    }
  }
}

resource "local_file" "second_inventory" {
  content  = yamlencode(local.special_config)
  filename = "vars.yaml"
}

That will create a second inventory file in your current directory looking like this:

"kubernetes":
  "vars":
    "kubernetes_init_skip_phases":
    - "kube-proxy"

Then you can reference that second inventory file like this

 ansible-playbook -i inventory.yaml -i vars.yaml ../../ansible-kubernetes/playbooks/install.yml

My inventory.yaml file

plugin: cloud.terraform.terraform_provider
project_path: .
# Terraform binary (available in the $PATH) or full path to the binary.
binary_path: terraform

You can target the groups/hosts in that second inventory file that you set in your terraform. I just created a kubernetes group for all of my kubernetes nodes. You could do all to have it apply to all hosts, or whatever other groups/hosts you want.