# Creating my first Action plugin and have a few questions

**URL:** <https://forum.ansible.com/t/creating-my-first-action-plugin-and-have-a-few-questions/38275>\
**Category:** Ansible Developer\
**Tags:** galaxy-ng\
**Created:** [July 28, 2023, 8:46pm UTC](https://forum.ansible.com/t/creating-my-first-action-plugin-and-have-a-few-questions/38275 "2023-07-28T20:46:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kent\_Larsson](https://avatars.discourse-cdn.com/v4/letter/k/fbc32d/32.png) [@Kent\_Larsson](https://forum.ansible.com/u/Kent_Larsson)\
**Post date:** [July 28, 2023, 8:46pm UTC](https://forum.ansible.com/t/creating-my-first-action-plugin-and-have-a-few-questions/38275/1 "2023-07-28T20:46:23Z")

</div>

Hello folks!

I’m creating an Action plugin to query a file for contents.

I aim to publish it at Ansible Galaxy for myself to use, and perhaps it will be useful for someone else as well. It’s my first Ansible plugin, and it’s been a couple of years since I last touched Python as well, so I am in need of some guidance.

I have this file tree:

ansible\_collections/  
└── myns  
└── query\_file  
├── galaxy.yml  
├── LICENSE  
├── meta  
│ └── runtime.yml  
├── plugins  
│ ├── action  
│ │ ├── args.json  
│ │ ├── query  
│ │ │ ├── config.py  
│ │ │ ├── parse.py  
│ │ │ ├── parse\_target\_container.py  
│ │ │ ├── select\_columns.py  
│ │ │ ├── target\_from.py  
│ │ │ ├── target.py  
│ │ │ ├── test\_parse\_dict.py  
│ │ │ ├── test\_parse\_list.py  
│ │ │ ├── test\_parse.py  
│ │ │ ├── test\_parse\_target\_container.py  
│ │ │ ├── test\_select\_columns.py  
│ │ │ ├── test\_shared.py  
│ │ │ ├── test\_target\_from\_string.py  
│ │ │ ├── test\_target\_init.py  
│ │ │ └── test\_target\_match\_in.py  
│ │ └── query\_file.py  
│ └── README.md  
├── README.md  
├── requirements.txt  
└── tests  
├── integration  
│ ├── inventory  
│ └── targets  
│ └── action\_query\_file  
│ └── tasks  
│ └── test\_x.yml  
└── unit  
└── plugins  
└── action  
└── test\_y.py

1. query\_file.py contains my class which extends ActionBase. I use some more modern stuff like types, @singledispatch, and @dataclass. I think it will be hard to support Python 2.7 so I thought I’d stick with Python 3 only. Does that decision make sense? I thought so since it’s been a while now since Python 2.7 become unsupported.

2. If I go for Python 3 only, is there something I should do for ansible-test sanity to pass? It complains about some missing Python versions.

3. Next to as a sibling to query\_file.py I have a directory named query. It contains the generic logic which is pure Python and does not require Ansible. I’d like to keep that code split up as it is. Is there a better, more “standard”, place for it?

4. The query directory contains tests as well. I like my tests next to the files being tested, but it seems Ansible prefers a tests directory. Should I move my tests there for them to be executed well in a pipeline?  
Thank you very much for taking the time to read this far! I hope there are some knowledgable people here who can provide some answers.

/ Kent

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 29, 2023, 4:41am UTC](https://forum.ansible.com/t/creating-my-first-action-plugin-and-have-a-few-questions/38275/2 "2023-07-29T04:41:07Z")

</div>

Hi,

> &nbsp;&nbsp;&nbsp;1. query\_file.py contains my class which extends ActionBase. I use  
> some more modern stuff like types, @singledispatch, and @dataclass. I  
> think it will be hard to support Python 2.7 so I thought I'd stick  
> with Python 3 only. Does that decision make sense? I thought so since  
> it's been a while now since Python 2.7 become unsupported.

If you want to support older ansible-core versions, you also should  
support Python 2.7, but if you stick to ansible-core 2.12+ there's no  
need for that. You can find a support matrix here:  
[https://docs.ansible.com/ansible/devel/reference\_appendices/release\_and\_maintenance.html#ansible-core-support-matrix](https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix)

If your collection supports (as declared in meta/runtime.yml)  
ansible-core 2.12+ or even requires a later version, you can stick to  
Python 3.8+ on the controller side (action plugins always run on the  
controller side).

> &nbsp;&nbsp;&nbsp;2. If I go for Python 3 only, is there something I should do for  
> &nbsp;&nbsp;&nbsp;ansible-test sanity to pass? It complains about some missing  
> Python versions.

Which ansible-core version are you using?

> &nbsp;&nbsp;&nbsp;3. Next to as a sibling to query\_file.py I have a directory named  
> query. It contains the generic logic which is pure Python and does  
> not require Ansible. I'd like to keep that code split up as it is. Is  
> there a better, more "standard", place for it?

The standard place would be somewhere in plugins/plugin\_utils/. Every  
file in plugins/action/ (and subdirectories) is supposed to be an  
action plugin. The JSON file in plugins/action/ might also cause  
problems.

Do document your plugin, you also need a module stub in  
plugins/modules/ with DOCUMENTATION, RETURN, and EXAMPLES.

> &nbsp;&nbsp;&nbsp;4. The query directory contains tests as well. I like my tests  
> next to the files being tested, but it seems Ansible prefers a tests  
> directory. Should I move my tests there for them to be executed well  
> in a pipeline?

ansible-test prefers tests for \<path\_to\_file\>/\<filebase\>.py to be in  
tests/unit/\<path\_to\_file\>/test\_\<filebase\>.py.

Regarding tests/integration:

> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;│ └── targets  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;│ └── action\_query\_file  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;│ └── tasks  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;│ └── test\_x.yml

you should have a main.yml in targets/action\_query\_file/tasks/.  
Integration tests are an Ansible role, and `ansible-test integration`  
uses the default entrypoint.

Cheers,  
Felix
