-
Notifications
You must be signed in to change notification settings - Fork 24
Description
SUMMARY
If .sops.yaml
config includes a path_regex
config that matches on directories (or parts of the path that are not the filename), the rule may fail to match: no matching creation rules found
It seems like this is because the module is only passing the filename to --filename-override
when it should be passing the full path (my best guess).
sops docs indicate that path_regex
matches on the absolute path.
ISSUE TYPE
- Bug Report
COMPONENT NAME
Module: community.sops.sops_encrypt
ANSIBLE VERSION
ansible [core 2.18.3]
config file = None
configured module search path = ['/Users/travisty/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /Users/travisty/projects/big-donut-infra/.venv/lib/python3.13/site-packages/ansible
ansible collection location = /Users/travisty/projects/big-donut-infra/.venv/galaxy
executable location = /Users/travisty/projects/big-donut-infra/.venv/bin/ansible
python version = 3.13.2 (main, Feb 4 2025, 14:51:09) [Clang 16.0.0 (clang-1600.0.26.6)] (/Users/travisty/projects/big-donut-infra/.venv/bin/python3)
jinja version = 3.1.6
libyaml = True
COLLECTION VERSION
ansible-galaxy collection list community.sops
# /Users/travisty/projects/big-donut-infra/.venv/galaxy/ansible_collections
Collection Version
-------------- -------
community.sops 2.0.3
CONFIGURATION
COLLECTIONS_PATHS(env: ANSIBLE_COLLECTIONS_PATH) = ['/Users/travisty/projects/big-donut-infra/.venv/galaxy']
CONFIG_FILE() = None
DEFAULT_ROLES_PATH(env: ANSIBLE_ROLES_PATH) = ['/Users/travisty/projects/big-donut-infra/.venv/galaxy/ansible_roles']
EDITOR(env: EDITOR) = zed-preview --wait
PAGER(env: PAGER) = less
VARIABLE_PLUGINS_ENABLED(env: ANSIBLE_VARS_ENABLED) = ['host_group_vars', 'community.sops.sops']
OS / ENVIRONMENT
- MacOS
sops 3.9.4 (latest)
STEPS TO REPRODUCE
See this repo for a minimal example case: https://github.com/TravisWhitehead/sops-ansible-path-regex-bug
Try to create an encrypted file with an absolute path; consider this task:
- name: Try encrypting example file
community.sops.sops_encrypt:
path: "output/examplesecret.sops.yaml"
content_yaml: '{{ "hello: world" | from_yaml }}'
# this is an example key
age: ["age187022d9nqqe79qaphrn99stjdyt26kchm539s5w2mljdtw0p7cvq4xwreu"]
mode: "0644"
force: true
Consider this .sops.yaml
config:
---
creation_rules:
# this fails because it tries to match on part of the path (output/)
- path_regex: output/examplesecret\.sops\.yaml
key_groups:
- age:
- "age187022d9nqqe79qaphrn99stjdyt26kchm539s5w2mljdtw0p7cvq4xwreu"
# this works because it is only matching on the filename
# - path_regex: examplesecret\.sops\.yaml
# key_groups:
# - age:
# - "age187022d9nqqe79qaphrn99stjdyt26kchm539s5w2mljdtw0p7cvq4xwreu"
EXPECTED RESULTS
The file should be encrypted/created successfully and match the rule with path_regex: output/examplesecret\.sops\.yaml
ACTUAL RESULTS
The module fails if matching on anything other than the filename.
The full traceback is:
File "/var/folders/96/zz_hxdnx5js100_hldblr4dm0000gq/T/ansible_community.sops.sops_encrypt_payload_s2e_1b3o/ansible_community.sops.sops_encrypt_payload.zip/ansible_collections/community/sops/plugins/modules/sops_encrypt.py", line 222, in main
data = Sops.encrypt(
data=input_data, cwd=directory, input_type=input_type, output_type=output_type,
filename=os.path.relpath(path, directory) if directory is not None else path,
get_option_value=get_option_value, module=module,
)
File "/var/folders/96/zz_hxdnx5js100_hldblr4dm0000gq/T/ansible_community.sops.sops_encrypt_payload_s2e_1b3o/ansible_community.sops.sops_encrypt_payload.zip/ansible_collections/community/sops/plugins/module_utils/sops.py", line 337, in encrypt
return runner.encrypt(
~~~~~~~~~~~~~~^
data,
^^^^^
...<4 lines>...
filename=filename,
^^^^^^^^^^^^^^^^^^
)
^
File "/var/folders/96/zz_hxdnx5js100_hldblr4dm0000gq/T/ansible_community.sops.sops_encrypt_payload_s2e_1b3o/ansible_community.sops.sops_encrypt_payload.zip/ansible_collections/community/sops/plugins/module_utils/sops.py", line 263, in encrypt
raise SopsError('to stdout', exit_code, err, decryption=False)
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"age": [
"age187022d9nqqe79qaphrn99stjdyt26kchm539s5w2mljdtw0p7cvq4xwreu"
],
"age_key": null,
"age_keyfile": null,
"attributes": null,
"aws_access_key_id": null,
"aws_profile": null,
"aws_secret_access_key": null,
"aws_session_token": null,
"azure_kv": null,
"config_path": null,
"content_binary": null,
"content_json": null,
"content_text": null,
"content_yaml": {
"hello": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
},
"enable_local_keyservice": false,
"encrypted_regex": null,
"encrypted_suffix": null,
"encryption_context": null,
"force": true,
"gcp_kms": null,
"group": null,
"hc_vault_transit": null,
"keyservice": null,
"kms": null,
"mode": "0644",
"owner": null,
"path": "output/examplesecret.sops.yaml",
"pgp": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"shamir_secret_sharing_threshold": null,
"sops_binary": null,
"unencrypted_regex": null,
"unencrypted_suffix": null,
"unsafe_writes": false
}
},
"msg": "error with file to stdout: ErrorGeneric exited with code 1: error loading config: no matching creation rules found\n"
}