# Struggling configuring argument specs for custom module

**URL:** <https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080>\
**Category:** Get Help\
**Tags:** dev\
**Created:** [May 30, 2024, 1:42pm UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080 "2024-05-30T13:42:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nikuiz](https://avatars.discourse-cdn.com/v4/letter/n/eb8c5e/32.png) [@nikuiz](https://forum.ansible.com/u/nikuiz)\
**Post date:** [May 30, 2024, 1:42pm UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080/1 "2024-05-30T13:42:26Z")

</div>

Hello! I’m developping a custom Ansible module and I’m struggling to set up mu argument specs. I’d like to add some conditionals to it ( like ‘required\_one\_of’, ‘required\_if’ ), but it looks like you’re only able to do it at the top level of the params dict.

Let me explain, here’s my argument specs :

```auto
module_args = {
        "config": {
            "elements": "dict",
            "options": {
                "interfaces": {"type": "str", "required": True},
                "vlan": {"type": "str"},
                "pvid": {"type": "str"},
            },
            "type": "list",
        }
    }

```

What i’d like to do is to make one of the following arguments required : vlan or pvid. I assume to achieve this I should do something like this :

```auto
module = AnsibleModule(
        argument_spec = module_args,
        required_one_of = [("config.vlan","config.pvid")],
        supports_check_mode = True
    )

```

But this doesn’t seem to work, because it looks for config.vlan and config.pvid keys at the top level of the params dict, and it doesn’t go inside of the config dict.

How can I achieve that?

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [May 30, 2024, 8:03pm UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080/2 "2024-05-30T20:03:45Z")

</div>

> [@nikuiz](#):
>
> I’d like to add some conditionals to it ( like `required_one_of`, `required_if` ), but it looks like you’re only able to do it at the top level of the params dict.

That’s not what the documentation says. If you read through [Ansible module architecture — Ansible Community Documentation](https://docs.ansible.com/ansible/latest/dev_guide/developing_program_flow_modules.html#argument-spec) you’ll see that those appear both in the list of behavioral attributes for arguments and as optional arguments for `AnsibleModule()`.

---

<div class="post-metadata">

**Author:** ![nikuiz](https://avatars.discourse-cdn.com/v4/letter/n/eb8c5e/32.png) [@nikuiz](https://forum.ansible.com/u/nikuiz)\
**Post date:** [May 31, 2024, 7:15am UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080/3 "2024-05-31T07:15:00Z")

</div>

I think there might be a misunderstanding. I understand that options as “required\_one\_of”, “mutually\_exclusive” etc are optional argument for AnsibleModule().

So, for example, with this specific argument\_spec dict :

```auto
module_args = {
        "config": {
            "elements": "dict",
            "options": {
                "interfaces": {"type": "str", "required": True},
                "vlan": {"type": "str"},
                "pvid": {"type": "str"}
            },
            "type": "list",
            "required": True
        },
        "argument_2": {"type": "str", "required": True},
        "argument_3": {"type": "int", "required": True},
    }

```

I would add this to my AnsibleModule() argument in order to mutually exclude argument\_2 and argument\_3

```auto
module = AnsibleModule(
  argument_spec,
  mutually_exclusive=[
    ('argument_2', 'argument_3'),
  ]
)

```

My question is, how can I achieve the same behaviour but with nested elements? For example, if I want to mutually exclude vlan and pvid inside of the config list, what would be the option argument “mutually\_exclusive” for AnsibleModule()

Thanks you!

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [May 31, 2024, 1:41pm UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080/4 "2024-05-31T13:41:12Z")

</div>

This seems to do what you want, in my limited testing:

```auto
module_args = {
        "config": {
            "elements": "dict",
            "options": {
                "interfaces": {"type": "str", "required": True},
                "vlan": {"type": "str"},
                "pvid": {"type": "str"}
            },
            "type": "list",
            "required": True,
            "mutually_exclusive": [["vlan", "pvid"]]
        },
    }

```

However, based on where you have your “`type: list`” and the use of the plural “`interfaces`” for what is a single string, my guess is you still have some issue to work through.

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [May 31, 2024, 3:53pm UTC](https://forum.ansible.com/t/struggling-configuring-argument-specs-for-custom-module/6080/5 "2024-05-31T15:53:59Z")

</div>

> [@nikuiz](#):
>
> I think there might be a misunderstanding. I understand that options as “required\_one\_of”, “mutually\_exclusive” etc are optional argument for AnsibleModule().

Again, that is not correct. They are behavioural attributes for arguments, _and also_ optional arguments for `AnsibleModule()`.

> [@nikuiz](#):
>
> For example, if I want to mutually exclude vlan and pvid inside of the config list, what would be the option argument “mutually\_exclusive” for AnsibleModule()

Nothing, because that’s the wrong place to put it. It belongs at the level where those arguments exist, not at the top level.
