ansible-community / molecule-plugins

Collection on molecule plugins
MIT License
109 stars 73 forks source link

Providing vpc_subnet_id, but failing one get_default_subnet #46

Closed natemarks closed 10 months ago

natemarks commented 2 years ago

I think it's failing because my account has neither a default vpc nor a default subnet - even though I do provide a vpc id and subnet id

My molecule yaml looks like this (redacted IDs):

---
dependency:
  name: galaxy
driver:
  name: ec2
platforms:
  - name: instance
    image_id: ami-abc123abc123
    instance_type: t2.micro
    region: us-east-1
    vpc_id: vpc-abc123abc123
    vpc_subnet_id: subnet-abc123abc123
    tags:
      - Name: molecule_instance
provisioner:
  name: ansible
verifier:
  name: ansible
stderr_lines": [
    "Traceback (most recent call last):",
    "  File \"/Users/nmarks/.ansible/tmp/ansible-tmp-1639218466.1749592-46512-137934100112825/AnsiballZ_ec2_instance.py\", line 107, in <module>",
    "    _ansiballz_main()",
    "  File \"/Users/nmarks/.ansible/tmp/ansible-tmp-1639218466.1749592-46512-137934100112825/AnsiballZ_ec2_instance.py\", line 99, in _ansiballz_main",
    "    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)",
    "  File \"/Users/nmarks/.ansible/tmp/ansible-tmp-1639218466.1749592-46512-137934100112825/AnsiballZ_ec2_instance.py\", line 47, in invoke_module",
    "    runpy.run_module(mod_name='ansible_collections.amazon.aws.plugins.modules.ec2_instance', init_globals=dict(_module_fqn='ansible_collections.amazon.aws.plugins.modules.ec2_instance', _modlib_path=modlib_path),",
    "  File \"/Users/nmarks/.pyenv/versions/3.9.2/lib/python3.9/runpy.py\", line 210, in run_module",
    "    return _run_module_code(code, init_globals, run_name, mod_spec)",
    "  File \"/Users/nmarks/.pyenv/versions/3.9.2/lib/python3.9/runpy.py\", line 97, in _run_module_code",
    "    _run_code(code, mod_globals, init_globals,",
    "  File \"/Users/nmarks/.pyenv/versions/3.9.2/lib/python3.9/runpy.py\", line 87, in _run_code",
    "    exec(code, run_globals)",
    "  File \"/var/folders/72/cmp8x83n3js_spr_3hvvdgch0000gn/T/ansible_ec2_instance_payload_1wo209qr/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 1910, in <module>",
    "  File \"/var/folders/72/cmp8x83n3js_spr_3hvvdgch0000gn/T/ansible_ec2_instance_payload_1wo209qr/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 1886, in main",
    "  File \"/var/folders/72/cmp8x83n3js_spr_3hvvdgch0000gn/T/ansible_ec2_instance_payload_1wo209qr/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 1794, in build_filters",
    "  File \"/var/folders/72/cmp8x83n3js_spr_3hvvdgch0000gn/T/ansible_ec2_instance_payload_1wo209qr/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 1446, in get_default_subnet",
    "TypeError: 'NoneType' object is not subscriptable"
  ],
natemarks commented 2 years ago

I was able to reproduce the problem. I tested the same config on a subnet in an account that has a default vpc/subnet and it worked. Then I moved back to the subnet in the account without a default vpc/subnet and it failed. then i created a default vpc/subnet and it worked.

I think the AWS best practices recommend deleting default VPC/subnets, so this should probably only look for them as a fallback

setswei commented 2 years ago

I too am running into this issue with the driver. I have created a default vpc which has worked around the problem but it would be great to see if the process can be skipped if VPC information is provided, as it is a best practice to delete all default vpcs (especially if they are not in use).

mihai-satmarean commented 2 years ago

having the same issue

dlouzan commented 1 year ago

What I have just found on 0.4 is that you are supposed to only pass vpc_subnet_id if you want to use a custom subnet id. Adding on top vpc_id will make it fail, because it will assume that you want to auto-create it in that case. Just removing vpc_id did work for me.

danielpodwysocki commented 10 months ago

https://github.com/ansible-collections/amazon.aws/blob/c9fd4b71ab1372a884afb0cc5179e736f31d324b/plugins/modules/ec2_instance.py#L2136

For reference, this is where in the code this hits.

danielpodwysocki commented 10 months ago
        if not module.params.get("vpc_subnet_id"):
            if module.params.get("network"):
                # grab AZ from one of the ENIs
                ints = module.params.get("network").get("interfaces")
                if ints:
                    filters["network-interface.network-interface-id"] = []
                    for i in ints:
                        if isinstance(i, dict):
                            i = i["id"]
                        filters["network-interface.network-interface-id"].append(i)
            else:
                sub = get_default_subnet(get_default_vpc(), availability_zone=module.params.get("availability_zone"))
                filters["subnet-id"] = sub["SubnetId"]

I was starting to do an overcomplicated fix, but seems all we need to do is ensure we pass the subnet_id and this will never get called.

We always require it regardless, so this is ok. Submitting a PR now.