Modules et plugins custom
Les modules communautaires couvrent la majorité des besoins. Il arrive cependant qu'une API interne ou une logique métier complexe nécessite un module sur mesure.
Structure d'un module Python
#!/usr/bin/python
# library/my_module.py
from ansible.module_utils.basic import AnsibleModule
def run_module():
argument_spec = dict(
name=dict(type="str", required=True),
state=dict(type="str", default="present", choices=["present", "absent"]),
url=dict(type="str", required=True),
token=dict(type="str", required=True, no_log=True),
)
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
name = module.params["name"]
state = module.params["state"]
# Vérifier l'état actuel (idempotence)
current = get_resource(module.params["url"], name)
if state == "present" and current is None:
if module.check_mode:
module.exit_json(changed=True, msg=f"Would create {name}")
create_resource(module.params["url"], name)
module.exit_json(changed=True, msg=f"Created {name}")
elif state == "absent" and current is not None:
if module.check_mode:
module.exit_json(changed=True, msg=f"Would delete {name}")
delete_resource(module.params["url"], name)
module.exit_json(changed=True, msg=f"Deleted {name}")
else:
module.exit_json(changed=False)
if __name__ == "__main__":
run_module()Placer dans library/ au niveau du projet. Disponible immédiatement dans les playbooks.
Filter plugins
# filter_plugins/my_filters.py
def mask_secret(value, visible=4):
if len(value) <= visible:
return "*" * len(value)
return "*" * (len(value) - visible) + value[-visible:]
class FilterModule:
def filters(self):
return {"mask_secret": mask_secret}{{ db_password | mask_secret(visible=4) }}Lookup plugins
# lookup_plugins/internal_vault.py
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
return [fetch_secret(term) for term in terms]- ansible.builtin.set_fact:
db_password: "{{ lookup('internal_vault', 'myapp/db_password') }}"Tests unitaires
# Test rapide
python library/my_module.py <<< '{"ANSIBLE_MODULE_ARGS": {"name": "test", "state": "present", "url": "http://api", "token": "tok"}}'
# Tests formels
ansible-test units --python 3.11