mantl / terraform.py

Ansible dynamic inventory script for parsing Terraform state files
Apache License 2.0
451 stars 122 forks source link

Error while generating inventory for DigitalOcean droplets #39

Closed fquffio closed 8 years ago

fquffio commented 8 years ago

If Terraform configuration consists of one (or more?) DigitalOcean droplets, terraform.py exists with error in case user_data key is missing in *.tfstate file. I haven't checked if this is a regression introduced in a recent version of Terraform.

Terraform and Dynamic Inventory script versions

$ terraform --version
Terraform v0.6.14
$ ./dynamic-inventory/terraform.py --version
./dynamic-inventory/terraform.py 0.3.0pre

Traceback

$ ./dynamic-inventory/terraform.py --list
Traceback (most recent call last):
  File "./dynamic-inventory/terraform.py", line 658, in <module>
    main()
  File "./dynamic-inventory/terraform.py", line 643, in main
    output = query_list(hosts)
  File "./dynamic-inventory/terraform.py", line 585, in query_list
    for name, attrs, hostgroups in hosts:
  File "./dynamic-inventory/terraform.py", line 67, in iterhosts
    yield parser(resource, module_name)
  File "./dynamic-inventory/terraform.py", line 83, in inner
    name, attrs, groups = func(*args, **kwargs)
  File "./dynamic-inventory/terraform.py", line 153, in digitalocean_host
    'metadata': json.loads(raw_attrs['user_data']),
KeyError: u'user_data'

Terraform *.tfstate file contents

{
    "version": 1,
    "serial": 54,
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {
            },
            "resources": {
                "digitalocean_droplet.galois": {
                    "type": "digitalocean_droplet",
                    "primary": {
                        "id": "<DROPLET ID>",
                        "attributes": {
                            "id": "<DROPLET ID>",
                            "image": "ubuntu-14-04-x64",
                            "ipv4_address": "<DROPLET IPv4>",
                            "ipv6": "true",
                            "ipv6_address": "<DROPLET IPv6>",
                            "ipv6_address_private": "",
                            "locked": "false",
                            "name": "galois.example.com",
                            "region": "fra1",
                            "size": "512mb",
                            "ssh_keys.#": "2",
                            "ssh_keys.0": "<SSH KEY #0>",
                            "ssh_keys.1": "<SSH KEY #1>",
                            "status": "active"
                        }
                    }
                }
            }
        }
    ]
}

Proposed fix

I found a fix that works for me, but could possibly break things for other people. Honestly I don't have time nor appropriate knowledges to deeply test this, so I'm just posting my patch, in case it is helpful to somebody.

diff --git a/terraform.py b/terraform.py
index cab214d..bd53589 100755
--- a/terraform.py
+++ b/terraform.py
@@ -150,7 +150,7 @@ def digitalocean_host(resource, tfvars=None):
         'image': raw_attrs['image'],
         'ipv4_address': raw_attrs['ipv4_address'],
         'locked': parse_bool(raw_attrs['locked']),
-        'metadata': json.loads(raw_attrs['user_data']),
+        'metadata': json.loads(raw_attrs.get('user_data', '{}')),
         'region': raw_attrs['region'],
         'size': raw_attrs['size'],
         'ssh_keys': parse_list(raw_attrs, 'ssh_keys'),
fquffio commented 8 years ago

Alright, I'm an idiot. This is the very same issue as #28. Sorry for duplicate.