Code Monkey home page Code Monkey logo

ansible-role-letsencrypt's Introduction

Ansible role to obtain Let's Encrypt SSL certificates

Integration Ansible Galaxy

This role is meant to request SSL certificates from Let's Encrypt, using the HTTP or the DNS challenge for their ACME API.

Features:

  • Installs and configures certbot and the DNS challenge helper script
  • Supports both the HTTP and the DNS challenge
    • For HTTP challenge, the authenticator plugins apache, nginx, standalone and webroot are supported
  • The DNS challenge uses a dedicated zone for AMCE challenge tokens only, lowering the security risks of dynamic updates. The concept is explained here
  • Restart of services at certificate renewal using post-hooks or custom post-hook command
  • Permission control to certificates using a dedicated system group

Supported distributions:

  • Debian 11 (Bullseye)
  • Debian 12 (Bookworm)

Tested on:

  • Debian 11 (Bullseye)
  • Debian 12 (Bookworm)
  • CentOS7
  • Ubuntu 2204 (Jammy Jellyfish)

It does the following:

  • When letsencrypt_setup is True (the default) this role will:

    • Install certbot
    • Register an account at Let's Encrypt
    • Install required files/keys for the DNS challenge
    • Create the system group 'letsencrypt'
  • When invoked with filled variable 'letsencrypt_cert':

    • Requests a SSL certificate via the Let's Encrypt ACME API, either using the HTTP challenge or using the DNS challenge
    • Optionally sets the post-hook for certificate renewals (to restart required services afterwards)
    • Optionally adds system users to the 'letsencrypt' system group to grant them read access to the SSL certificates and their private keys

How it works (examples)

  • Installation of certbot ansible-playbook site.yml -l localhost -t letsencrypt
  • Creation of a certificate via HTTP challenge and with webroot authenticator (restarting service 'apache2' at renewal): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub.example.org","domains":["sub.example.org"],"challenge":"http","http_auth":"webroot","webroot_path":"/var/www/sub.example.org","services":["apache2"]}}'
  • Creation of a certificate via DNS challenge (granting read access to certs to user 'Debian-exim', restarting services 'exim4' and 'dovecot` at renewal): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub2","domains":["sub2.example.org","sub2.another.example.org"],"challenge":"dns","services":["dovecot","exim4"],"users":["Debian-exim"]}}'
  • Creation of a certificate via HTTP challenge and with standalone authenticator (re-using same private key at renewal and running a custom post-hook script at renewal): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub3","domains":["sub3.example.org"],"challenge":"http","http_auth":"standalone","reuse_key":True,"post_hook":"/usr/local/bin/cert-post-hook.sh"}}'

Expected structure of variable letsencrypt_cert

The variable letsencrypt_cert is expected to be a dictionary:

letsencrypt_opts_extra: "--register-unsafely-without-email"
letsencrypt_cert:
  name: sub.example.org
  domains:
    - sub.example.org
  challenge: http
  http_auth: webroot
  webroot_path: /var/www/sub.example.org
  services:
    - apache2

or:

letsencrypt_cert:
  name: sub2
  domains:
    - sub2.example.org
    - sub2.another.example.org
  challenge: dns
  services:
    - dovecot
    - exim4
  users:
    - Debian-exim

or:

letsencrypt_cert:
  name: sub3
  domains:
    - sub3.example.org
  challenge: http
  http_auth: standalone
  reuse_key: True
  post_hook: "/usr/local/bin/cert-post-hook.sh"
letsencrypt_cert:
  name: sub3
  domains:
    - sub3.example.org
  challenge: http
  http_auth: standalone
  reuse_key: True
  deploy_hook: "/usr/local/bin/cert-post-hook.sh"

The dictionary supports the following keys:

  • name: name of the certificate [optional]
  • domains: list of domains for the certificate [required]
  • challenge: 'http' or 'dns' [required]
    • for challenge 'http': http_auth: 'webroot', 'apache' or 'nginx' [optional, default 'webroot']
      • for http_auth 'webroot': webroot_path [optional, default '/var/www']
  • services: list of services to be restarted in the post-hook [optional]
  • reuse_key: Reuse same private key at certificate renewal. 'True' or 'False' (default 'False')
  • post_hook: Custom post-hook to be executed after attempt to obtain/renew a certificate [optional]
  • deploy_hook: Custom deploy-hook to be executed after a successful attempt to obtain/renew a certificate [optional]
  • renew_hook: Custom renew-hook to be executed once for each renewed certificate after certificate renewal [optional]
  • users: list of users to be added to system group 'letsencrypt' [optional]

General Preliminaries

The role takes care of installing certbot and requesting SSL certificates using either the HTTP or the DNS challenge. It doesn't install or configure the required infrastructure (i.e. the Apache webserver or a DNS server).

The role is tested with Ansible 2.2 only. No guaranties that it runs with earlier versions of Ansible.

The HTTP challenge

Requirements:

  • The domain name(s) of the requested certificate has to point to the system
  • For http_auth 'apache', Apache2 has to be installed (and configured) on the system
  • For http_auth 'nginx', NGINX has to be installed (and configured) on the system

The DNS challenge

Requirements:

  • A DNS server with a dedicated zone, used for the ACME DNS challenge only. This zone has to allow dynamic DNS updates (NSUPDATE) for TXT records (see below).
  • CNAME records for _acme-challenge.sub.example.org for all domain names(s) of the requested certificate have to point to sub.example.org._le.example.org (inside the dedicated zone for the ACME DNS challenge).
  • The content of the DNS update key and private DNS update keys need to be available in the Ansible vars letsencrypt_ddns_key and letsencrypt_ddns_privkey (preferably inside a vault).

This role installs a helper script for the DNS challenge to /usr/local/bin/certbot-dns-hook.sh. This script will add the validation token to the TXT record at sub.example.org._le.example.org during the DNS challenge and remove it afterwards.

Wildcard support with the DNS challenge

Obtaining wildcard certificates should work out of the box via DNS challenge.

Configuring bind9 for the DNS challenge

(Another option would be to use the acme-dns server for this)

Generate a key for dynamic updates:

cd /etc/bind/keys
dnssec-keygen -a HMAC-SHA512 -b 512 -n USER _le.example.org_ddns_update
chown -R bind:bind /etc/bind/keys

Add the key to your bind config (e.g. at /etc/bind/named.conf.options):

key "_le.example.org_ddns_update" {
	algorithm hmac-sha512;
	secret "...";
};

Create the zone for dynamic updates:

$ORIGIN .
$TTL 86400	; 1 day
_le.example.org		IN SOA	ns1.example.org. postmaster.example.org. (
				2017061501 ; serial
				86400      ; refresh (1 day)
				3600       ; retry (1 hour)
				2419200    ; expire (4 weeks)
				86400      ; minimum (1 day)
				)
			NS	ns1.example.org.
			NS	ns2.example.org.
			TXT	"v=spf1 -all"

and configure it in your bind config (e.g. at /etc/bind/named.conf.local):

zone "_le.example.org" {
	type master;
	file "/etc/bind/zones/db._le.example.org";
	update-policy { grant _le.example.org_ddns_update wildcard *._le.example.org. TXT; };
};

Format for /etc/letsencrypt/keys/ddns_update.key (from bind)

key "<key>" {
    algorithm HMAC-SHA512;
    secret "<key>";
};

Format for /etc/letsencrypt/keys/ddns_update.private

Private-key-format: v1.3
Algorithm: 165 (HMAC_SHA512)
Key: <key>
Bits: AAA=
Created: 20181017144534
Publish: 20181017144534
Activate: 20181017144534

Ansible variable defaults

# Perform setup step; set false to disable
letsencrypt_setup: True

# Provide existing account data to be copied over
letsencrypt_account: ""
# letsencrypt_account:
#   hash: 1234567890abcdef1234567890abcdef
#   id: 123456789
#   creation_host: localhost
#   creation_dt: 2020-12-13T13:12:00Z
#   private_key:
#     n: 1234
#     e: 5678
#     d: 90ab
#     p: cdef
#     q: 1234
#     dp: 5678
#     dq: 90ab
#     qi: cdef
#     kty: RSA

# Set the email address associated with the Let's Encrypt account
letsencrypt_account_email: ""

# Default authenticator for the HTTP challenge ('webroot' or 'apache')
letsencrypt_http_auth: webroot

# Default webroot path for the authenticator 'webroot'
letsencrypt_webroot_path: /var/www

# Install the DNS challenge helper script and DNS update key
letsencrypt_dns_challenge: yes

# Settings for the dynamic DNS zone updates
# letsencrypt_ddns_server: ""
# letsencrypt_ddns_zone: ""
# letsencrypt_ddns_key: ""
# letsencrypt_ddns_privkey: ""

# Create system group 'letsencrypt' for access to certificates
letsencrypt_group: yes

# Reuse private key at certificate renewal?
letsencrypt_reuse_key: False

# Allow subset of names?
letsencrypt_subset_names: True

# Set global extra commandline options for certbot
letsencrypt_opts_extra: ""

# Set path for letsencrypt directory (no trailing "/" !!)
letsencrypt_directory: /etc/letsencrypt

Testing

For testing purposes, variable letsencrypt_test can be set. If set to True, the role will use Let's Encrypt test servers for account creation and obtaining the certificate.

For developing and testing the role we use Molecule and Vagrant/Github Actions. On the local environment you can easily test the role with

molecule test

License

This Ansible role is licensed under the GNU GPLv3.

Author

Copyright 2017-2019 systemli.org (https://www.systemli.org/)

ansible-role-letsencrypt's People

Contributors

0x46616c6b avatar akaihola avatar clepnicx avatar cyroxx avatar dependabot[bot] avatar doobry-systemli avatar goetzk avatar kmille avatar patsevanton avatar stroobl avatar t2d avatar xshadow avatar zxyz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ansible-role-letsencrypt's Issues

How to install certbot (and dependencies) when all variables set

ansible-role-letsencrypt/tasks/main.yml

  • include: install.yml
    when: not letsencrypt_cert|d()

  • include: certificate.yml
    when: letsencrypt_cert|d()

How is this supposed to work? Do we need a seperate setup phase or what is best practice to make it work?

We tried to setup with the role, but if we preconfigure all variables, the install does not run (which makes sense with the above code). But how can we install it then when we have a new server and with following the role logic and following the best practices.

Support --register-unsafely-without-email

Hello,

We don't want to receive any emails regarding let's encrypt (certs are monitored via other means).

Would it be possible to support the option --register-unsafely-without-email which would avoid setting an email address at all? Thanks a lot!

cant seem to get dns challange to work

TASK [ansible-role-letsencrypt : register Let's Encrypt certificate with DNS challenge] ************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["certbot", "certonly", "--manual", "--cert-name", "vizotest", "--domains", "vizowuzherealso.iccchem.com", "--preferred-challenge=dns", "--keep-until-expiring", "--expand", "--allow-subset-of-names", "--non-interactive", "--agree-tos", "--manual-public-ip-logging-ok", "--manual-auth-hook", "certbot-dns-hook.sh auth", "--manual-cleanup-hook", "certbot-dns-hook.sh cleanup"], "delta": "0:00:28.315553", "end": "2021-05-25 11:58:09.918568", "msg": "non-zero return code", "rc": 1, "start": "2021-05-25 11:57:41.603015", "stderr": "Saving debug log to /var/log/letsencrypt/letsencrypt.log\nPlugins selected: Authenticator manual, Installer None\nObtaining a new certificate\nPerforming the following challenges:\ndns-01 challenge for vizowuzherealso.iccchem.com\nHook command "certbot-dns-hook.sh auth" returned error code 2\nError output from certbot-dns-hook.sh:\n; Communication with 160.72.174.202#53 failed: timed out\n\nWaiting for verification...\nChallenge failed for domain vizowuzherealso.iccchem.com\nCleaning up challenges\nHook command "certbot-dns-hook.sh cleanup" returned error code 2\nError output from certbot-dns-hook.sh:\n; Communication with 160.72.174.202#53 failed: timed out\n\nChallenges failed for all domains", "stderr_lines": ["Saving debug log to /var/log/letsencrypt/letsencrypt.log", "Plugins selected: Authenticator manual, Installer None", "Obtaining a new certificate", "Performing the following challenges:", "dns-01 challenge for vizowuzherealso.iccchem.com", "Hook command "certbot-dns-hook.sh auth" returned error code 2", "Error output from certbot-dns-hook.sh:", "; Communication with 160.72.174.202#53 failed: timed out", "", "Waiting for verification...", "Challenge failed for domain vizowuzherealso.iccchem.com", "Cleaning up challenges", "Hook command "certbot-dns-hook.sh cleanup" returned error code 2", "Error output from certbot-dns-hook.sh:", "; Communication with 160.72.174.202#53 failed: timed out", "", "Challenges failed for all domains"], "stdout": "", "stdout_lines": []}

I dont know why it doesnt complete. I makes all the appropriate records it seems, I cant seem to get it to finish

"Too many levels of symbolic links (40)"

When using this role in Vagrant, rsync fails because of "Too many levels of symbolic links (40)".
The error log also shows a recursive loop:

[...]/vendor/roles/letsencrypt_cert/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/default/roles/ansible-role-letsencrypt/molecule/[...]

What can be the reason for this?

Nginx TLS config is not applied to virtual host

Hello,

Trying to use this role on Debian 12
Using as:

---
- name: Setup reverse proxy
  hosts: [monitoring]
  vars_files:
    - vars/main.yml
  vars:
    letsencrypt_account_email: "[email protected]"
  roles:
    - jdauphant.nginx
    - systemli.letsencrypt

# vars/main.yml
nginx_sites:
  default:
    - listen 80
    - server_name mydomain.com
    - location / { proxy_pass http://localhost:8000; }

letsencrypt_account_email: "[email protected]"
letsencrypt_cert:
  name: mydomain.com
  challenge: http
  http_auth: nginx
  letsencrypt_account_email: "[email protected]"
  domains:
    - mydomain.com

I would expect TLS config to be applied, but it runs like:

- name: Register Let's Encrypt certificate with HTTP challenge
  ansible.builtin.command: >
    certbot certonly
    ...

I would expect it to be:

- name: Register Let's Encrypt certificate with HTTP challenge
  ansible.builtin.command: >
    certbot run
    ...

Otherwise virtual host TLS configuration is not applied. Only certificate is fetched.
Runninng cerbot manually fixes the issue:

certbot run --nginx -n --domains mydomain.com

Support renew_hook

Hello,

Could you please support renew-hook as well? This is only executed on successful renewal.

post-hook is executed on each attempt of certbot to renew the cert (even if that fails), something we certainly want to avoid.

Thanks a lot for taking this into consideration

Multiple certificates ?

Hello,

I look for a role that uses webroot mode, and this one seams good!
But reading quickly the code, I guess it only manage one certificate (eventually with multiple domains).

Is there something I miss to manage multiple certificates?
Best regards

Error: either set letsencrypt_account_email or add ''--register-unsafely-without-email'' to letsencrypt_opts_extra'

Hello! Thanks for role letsencrypt
Try install

Playbook

- hosts: letsencrypt
  become: true
  roles:
    - role: systemli.letsencrypt

Inventory

all:
  children:
    letsencrypt:
      hosts:
        "letsencrypt":
          ansible_host: "xxx"
  vars:
    letsencrypt_cert:
      name: letsencrypt.xxxx.sslip.io
      domains:
        - letsencrypt.xxxx.sslip.io
      challenge: http
      http_auth: webroot
      opts_extra: "--register-unsafely-without-email"
      webroot_path: /var/www/letsencrypt.xxxxx.sslip.io
      services:
        - apache2

Output

TASK [systemli.letsencrypt : check if letsencrypt_account_email is set] ****************************************************************************************************************
Tuesday 26 April 2022  10:50:00 +0600 (0:00:01.529)       0:00:48.926 *********
fatal: [letsencrypt]: FAILED! => changed=false
  msg: 'Error: either set letsencrypt_account_email or add ''--register-unsafely-without-email'' to letsencrypt_opts_extra'

Fix deprecation warnings

I get this warning using the letsencrypt role with ansible 2.4:

[DEPRECATION WARNING]: The use of 'include' for tasks has been deprecated. Use 'import_tasks' for static inclusions or 'include_tasks' for dynamic inclusions. This feature will be removed in a future release. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

I guess it's these includes in main.yml:

tasks/main.yml:- include: install.yml
tasks/main.yml:- include: certificate.yml

Provide a variable for the letsencrypt directory

The role is rather opinionated in that the letsencrypt must be /etc/letsencrypt.

It would be great to have that as a variable that could be defined, but use that directory as the default. It makes it rather complicated to use it in a container by hardcoding the directory like that.

Role requires multiple plays to complete

Hi,
I'm wondering if you are willing to include a change like the one below from @kmille to remove the two part setup of this role.

kmille@e2ed450

Detailed background:
It turns out this play requires two runs: first with no configuration then one with the certificates to set up.
In the example below, the first play is only required so letsencrypt_cert can be empty during install.

 cat playbook.yaml
---

- hosts: example.com
  vars:
    letsencrypt_cert: []
  roles:
  - weareinteractive.apt
  - systemli.letsencrypt

- hosts: example.com
  roles:
  - systemli.letsencrypt
  - weareinteractive.nginx


 cat host_vars/example.com
---
apt_packages:
  - zip
  - nginx

# [nginx config]

letsencrypt_account_name: 'example@example'
letsencrypt_account_email: "{{ letsencrypt_account_name }}"
letsencrypt_http_auth: standalone
letsencrypt_dns_challenge: no
# Should probably try and fiddle things so this works
letsencrypt_group: no

letsencrypt_cert:
  name: "{{ bitwarden_domain }}"
  domains:
    - "{{ bitwarden_domain }}"
  challenge: http
  http_auth: standalone
```

Remove `letsencrypt_webserver_groupname`?

While working on #50, I found it rather surprising that I needed to make sure that a host that uses the http challenge needs to be in the correct letsencrypt_webserver_groupname (default: web).

What is the reasoning behind this?
Shouldn't it be enough that we choose the http challenge and set letsencrypt_http_auth if required?

Doesn't fail when DNS isn't configured for vhost

We have a problem with multiple domains that we want to configure.

It continuous the task when 1 domain fails. We have fixed this with failed_when: "'failed' in letsencrypt_reg_certbot_http.stderr". Do you have a better solution or a another methode?

If this is the good way, can you apply this on your letsencrypt role.

Output:
{
"_ansible_parsed": true,
"stderr_lines": [
"Saving debug log to /var/log/letsencrypt/letsencrypt.log",
"Plugins selected: Authenticator webroot, Installer None",
"Renewing an existing certificate",
"Performing the following challenges:",
"http-01 challenge for deployservertest2.hosted-power.com",
"http-01 challenge for deployservertest.hosted-power.com",
"Using the webroot path /var/www/letsencrypt for all unmatched domains.",
"Waiting for verification...",
"Challenge failed for domain deployservertest.hosted-power.com",
"Cleaning up challenges",
"Performing the following challenges:",
"http-01 challenge for deployservertest2.hosted-power.com",
"Using the webroot path /var/www/letsencrypt for all unmatched domains.",
"Waiting for verification...",
"Cleaning up challenges",
"Running deploy-hook command: /root/letsencryptrenew.bash"
],

Letsencrpyt role tasks (register):

  • name: register Let's Encrypt certificate with HTTP challenge
    command: >
    certbot certonly
    {{ letsencrypt_opt_http_auth|default() }}
    {{ letsencrypt_opt_cert_name|default() }}
    {{ letsencrypt_opt_test_cert|default() }}
    {{ letsencrypt_cert.opts_extra|default(letsencrypt_opts_extra|default()) }}
    --domains {{ letsencrypt_cert.domains|join(',') }}
    --keep-until-expiring --expand --allow-subset-of-names
    --non-interactive --agree-tos
    {{ letsencrypt_opt_renew_hook|default() }}
    when: letsencrypt_cert.challenge|default() == 'http' and letsencrypt_cert.domains|default()
    register: letsencrypt_reg_certbot_http
    changed_when: not "no action taken" in letsencrypt_reg_certbot_http.stdout
    failed_when: "'failed' in letsencrypt_reg_certbot_http.stderr"

wrong hostname

Hello
The certificate is using a wrong hostname

  • I've corrected the hostname with hostname
  • correctly set a reverse dns
  • check the nginx servername

but it still continue to provide me a wrong certificate
Could you please brings more information in the documentation.
I'm clueless

Thanks
Cedric

letsencrypt_opt_test_cert is undefined

Found a minor issue when the acme account is not created. The playbook fails at task Create new Let's Encrypt account.

fatal: [sub.example.org]: FAILED! =>
  msg: |-
    The task includes an option with an undefined variable. The error was: 'letsencrypt_opt_test_cert' is undefined. 'letsencrypt_opt_test_cert' is undefined

    The error appears to be in '/home/user/linux-maintenance/roles/ansible-role-letsencrypt/tasks/account.yml': line 54, column 5, but may
    be elsewhere in the file depending on the exact syntax problem.

    The offending line appears to be:


      - name: Create new Let's Encrypt account
        ^ here

Looking at the code it seems the issue stems from 'letsencrypt_opt_test_cert' gets defined in certificate.yml but the var is used earlier in account.yml beforce being properly defined.

The easiest solution seems to be simply moving the set_fact that defines the var into account.yml.

Allow account without email

Hi,

We use extra paramteter: --register-unsafely-without-email

However it interferes with account creation. In the past we managed to skip it better.

Could you fix it somehow that we can also generate certs without email? We're not interested at all in getting any email feedback ever :)

How to include this role?

- hosts: web
  become: yes

  tasks:
    - name: Include letsencrypt_cert
      include_role:
        name: letsencrypt_cert
      vars:
        letsencrypt_account_email: [email protected]
        letsencrypt_cert:
          name: staging.example.com
          domains:
            - staging.example.com
          challenge: http
          http_auth: apache
          opts_extra: '--server https://localca/acme/acme/directory'
          services:
            - apache2

The task name is logged during the run - but nothing else happens and no certificate is signed.

Could not choose appropriate plugin: The requested apache plugin does not appear to be installed

Hello! Thanks for role letsencrypt
I try install

Playbook

- hosts: letsencrypt
  become: true
  roles:
    - role: geerlingguy.apache
    - role: systemli.letsencrypt

Inventory

all:
  children:
    letsencrypt:
      hosts:
        "letsencrypt":
          ansible_host: "xxxx"
  vars:
    apache_vhosts:
      - servername: "letsencrypt.xxx.sslip.io"
        documentroot: "/var/www/html"
    letsencrypt_opts_extra: "--register-unsafely-without-email"
    letsencrypt_cert:
      name: letsencrypt.xxx.sslip.io
      domains:
        - letsencrypt.xxx.sslip.io
      challenge: http
      http_auth: apache
      services:
        - apache2

Output

TASK [systemli.letsencrypt : register Let's Encrypt certificate with HTTP challenge] ***************************************************************************************************
Tuesday 26 April 2022  12:07:16 +0600 (0:00:00.024)       0:01:19.398 *********
fatal: [letsencrypt]: FAILED! => changed=true
  cmd:
  - certbot
  - certonly
  - --apache
  - --cert-name
  - letsencrypt.51.250.21.141.sslip.io
  - --register-unsafely-without-email
  - --domains
  - letsencrypt.51.250.21.141.sslip.io
  - --keep-until-expiring
  - --expand
  - --allow-subset-of-names
  - --non-interactive
  - --agree-tos
  - --post-hook
  - systemctl restart apache2
  delta: '0:00:00.306110'
  end: '2022-04-26 06:07:20.466023'
  msg: non-zero return code
  rc: 1
  start: '2022-04-26 06:07:20.159913'
  stderr: |-
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Could not choose appropriate plugin: The requested apache plugin does not appear to be installed
    The requested apache plugin does not appear to be installed
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>

Fails at TASK [letsencrypt : register Let's Encrypt certificate with DNS challenge]

I'm having a problem using this role with https://github.com/systemli/ansible-role-mumble

TASK [letsencrypt : register Let's Encrypt certificate with DNS challenge]
fatal: [instance-2a]: FAILED! => {
    "msg": "The conditional check 'not \"no action taken\" in letsencrypt_reg_certbot_dns.stdout' failed. The error was: error while evaluating conditional (not \"no action taken\" in letsencrypt_reg_certbot_dns.stdout): Unable to look up a name or access an attribute in template string ({% if not \"no action taken\" in letsencrypt_reg_certbot_dns.stdout %} True {% else %} False {% endif %}).\nMake sure your variable name does not contain invalid characters like '-': argument of type 'StrictUndefined' is not iterable"
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.