Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable auth with third party services via environment variables for ansible-acme #40

Closed
jimkoen opened this issue Nov 5, 2022 · 5 comments · Fixed by #42
Closed

Enable auth with third party services via environment variables for ansible-acme #40

jimkoen opened this issue Nov 5, 2022 · 5 comments · Fixed by #42

Comments

@jimkoen
Copy link
Contributor

jimkoen commented Nov 5, 2022

Right now, there exist separate variables for every auth option for every auth provider.
Example:

- name: Creating challenge DNS entries for {{ ', '.join(acme_certificate_domains + acme_certificate_ips) }} via Route53
  community.aws.route53:   # noqa fqcn[canonical]
    state: present
    zone: "{{ item.key | community.dns.get_registrable_domain }}"
    record: "{{ item.key }}"
    type: TXT
    ttl: 60
    value: "{{ item.value | map('regex_replace', '^(.*)$', '\"\\1\"') | list }}"
    overwrite: true
    aws_access_key: "{{ acme_certificate_aws_access_key }}" # <----- this
    aws_secret_key: "{{ acme_certificate_aws_secret_key }}" # <----- this

This is imo a bit messy, as it requires users to manually override role vars in their plays,
instead of using environment variables that contain auth credentials, if so desired.

It's possible that users may want to use different credentials to interact with a multitude of cloud environments, but per default I feel it would be sensible to check if the environment variables for a specific provider are defined, and if so use them to authenticate instead.

See what I mean here:

https://docs.ansible.com/ansible/latest/collections/amazon/aws/docsite/aws_ec2_guide.html#authentication

@felixfontein
Copy link
Owner

Changing aws_access_key: "{{ acme_certificate_aws_access_key }}" to aws_access_key: "{{ acme_certificate_aws_access_key | default(omit) }}" (and removing the sanity checks that validate that these variables have been provided) should fix this.

The main downside is that you only find out that you forgot to specify something when the DNS module fails, instead of being informed before the private key is regenerated.

@jimkoen
Copy link
Contributor Author

jimkoen commented Nov 7, 2022

Changing aws_access_key: "{{ acme_certificate_aws_access_key }}" to aws_access_key: "{{ acme_certificate_aws_access_key | default(omit) }}" (and removing the sanity checks that validate that these variables have been provided) should fix this.

The main downside is that you only find out that you forgot to specify something when the DNS module fails, instead of being informed before the private key is regenerated.

Should I submit a PR to fix this? I am currently also working on adding OpenStack support.

The main downside is that you only find out that you forgot to specify something when the DNS module fails, instead of being informed before the private key is regenerated.

I'd have to modify files in my CI/CD workflow in order to inject the auth credentials into my playbooks.
For openstack modules, they check if a specific config file is present on the system and use the information contained within to authenticate. This is great for CI/CD, as I can supply this file as a template in my CI setup, making use of secrets.

For CI environments where injecting files or templates doesn't work, you could still use environment variables to pass the auth info.

The more sensible thing would be to issue a notice/warning when the credentials are not defined,
or create a variable to explicitly skip credentials verfification if warnings are not wanted.

EDIT: To clarify, my issue lies with checking in my credentials into git as plaintext inside the playbooks. Checking for env variables brings back the sanity checks. Checking the role vars is imo unecessary, as I expect someone using AWS to know the auth requirements of the AWS modules (this goes for any cloud)

@felixfontein
Copy link
Owner

I'll reply to the remainder later (sorry I'm somewhat busy right now), but let me reply to this already:

EDIT: To clarify, my issue lies with checking in my credentials into git as plaintext inside the playbooks. Checking for env variables brings back the sanity checks. Checking the role vars is imo unecessary, as I expect someone using AWS to know the auth requirements of the AWS modules (this goes for any cloud)

I'm not sure why you would want to do that. What folks commonly do is fill in variables from encrypted sources, for example Ansible vault, sops (via lookup or vars plugin), Hashi Vault (via lookup), passwordstore (via lookup), ...

For example, in my Let's Encrypt renewal playbook, I'm using vars: acme_certificate_hosttech_token: '{{ hosttech_dns_token }}', and hosttech_dns_token comes from a sops encrypted YAML file (loaded with community.sops.load_vars).

@jimkoen
Copy link
Contributor Author

jimkoen commented Nov 11, 2022

I'll reply to the remainder later (sorry I'm somewhat busy right now), but let me reply to this already:

EDIT: To clarify, my issue lies with checking in my credentials into git as plaintext inside the playbooks. Checking for env variables brings back the sanity checks. Checking the role vars is imo unecessary, as I expect someone using AWS to know the auth requirements of the AWS modules (this goes for any cloud)

I'm not sure why you would want to do that. What folks commonly do is fill in variables from encrypted sources, for example Ansible vault, sops (via lookup or vars plugin), Hashi Vault (via lookup), passwordstore (via lookup), ...

For example, in my Let's Encrypt renewal playbook, I'm using vars: acme_certificate_hosttech_token: '{{ hosttech_dns_token }}', and hosttech_dns_token comes from a sops encrypted YAML file (loaded with community.sops.load_vars).

I was only referring to the auth credentials from a specific cloud provider, not auth credentials overall.
Most cloud providers support setting them via a config file on some known path, that is then implicitly looked up (clouds.yaml for OpenStack for example) or via environment variables inside the users shells rc file (AWS for example).

Specifically:

https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_instance_module.html#parameter-aws_secret_key

AWS secret key. If not set then the value of the AWS_SECRET_ACCESS_KEY, AWS_SECRET_KEY, or EC2_SECRET_KEY environment variable is used.

Meaning you eliminate the need for encrypted files all together by just using environment variables. At least for those parts of the playbook that interact with your cloud.

@felixfontein
Copy link
Owner

I've implemented this in #42.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants