mirror of
				https://github.com/krislamo/puppet-acme_vault
				synced 2025-11-04 08:38:33 +00:00 
			
		
		
		
	Improve docs, scripts, and source .bashrc in cron
- Added comprehensive documentation for all Puppet classes - Applied bash linting and made minor improvements to check_cert.sh - Updated domain issue cron to source the .bashrc file - Implemented small changes to address Puppet linting issues
This commit is contained in:
		@@ -27,10 +27,10 @@ deploy_cert() {
 | 
			
		||||
    EXISTING_FULLCHAIN_PATH=$8
 | 
			
		||||
    
 | 
			
		||||
    echo "deploying cert to $EXISTING_CERT_PATH"
 | 
			
		||||
    echo "$NEWCERT" > $EXISTING_CERT_PATH
 | 
			
		||||
    echo "$NEWKEY"  > $EXISTING_KEY_PATH
 | 
			
		||||
    echo "$NEWCHAIN"  > $EXISTING_CHAIN_PATH
 | 
			
		||||
    echo "$NEWFULLCHAIN"  > $EXISTING_FULLCHAIN_PATH
 | 
			
		||||
    echo "$NEWCERT" > "$EXISTING_CERT_PATH"
 | 
			
		||||
    echo "$NEWKEY"  > "$EXISTING_KEY_PATH"
 | 
			
		||||
    echo "$NEWCHAIN"  > "$EXISTING_CHAIN_PATH"
 | 
			
		||||
    echo "$NEWFULLCHAIN"  > "$EXISTING_FULLCHAIN_PATH"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -44,10 +44,9 @@ EXISTING_CHAIN_PATH="${EXISTING_CERT_DIR}/chain.pem"
 | 
			
		||||
EXISTING_FULLCHAIN_PATH="${EXISTING_CERT_DIR}/fullchain.pem"
 | 
			
		||||
 | 
			
		||||
# variables
 | 
			
		||||
ONE_WEEK=604800
 | 
			
		||||
TODAY=$(date --iso-8601)
 | 
			
		||||
# use VAULT_BIN if defined, otherwise, assume /usr/local/bin/vault
 | 
			
		||||
: ${VAULT_BIN:="/usr/local/bin/vault"}
 | 
			
		||||
: "${VAULT_BIN:=/usr/local/bin/vault}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NEWCERT_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/cert.pem"
 | 
			
		||||
@@ -56,10 +55,10 @@ NEWCHAIN_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/chain.pem"
 | 
			
		||||
NEWFULLCHAIN_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/fullchain.pem"
 | 
			
		||||
 | 
			
		||||
# Get new cert info
 | 
			
		||||
NEWCERT=$($VAULT_BIN kv get -field=value $NEWCERT_VAULT_PATH) || exit -1
 | 
			
		||||
NEWKEY=$($VAULT_BIN kv get -field=value $NEWKEY_VAULT_PATH) || exit -1
 | 
			
		||||
NEWCHAIN=$($VAULT_BIN kv get -field=value $NEWCHAIN_VAULT_PATH) || exit -1
 | 
			
		||||
NEWFULLCHAIN=$($VAULT_BIN kv get -field=value $NEWFULLCHAIN_VAULT_PATH) || exit -1
 | 
			
		||||
NEWCERT=$($VAULT_BIN kv get -field=value "$NEWCERT_VAULT_PATH") || exit 1
 | 
			
		||||
NEWKEY=$($VAULT_BIN kv get -field=value "$NEWKEY_VAULT_PATH") || exit 1
 | 
			
		||||
NEWCHAIN=$($VAULT_BIN kv get -field=value "$NEWCHAIN_VAULT_PATH") || exit 1
 | 
			
		||||
NEWFULLCHAIN=$($VAULT_BIN kv get -field=value "$NEWFULLCHAIN_VAULT_PATH") || exit 1
 | 
			
		||||
NEWCERT_FINGERPRINT=$(get_fingerprint "$NEWCERT")
 | 
			
		||||
NEWCERT_ENDDATE=$(get_enddate "$NEWCERT")
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +66,7 @@ NEWCERT_ENDDATE=$(get_enddate "$NEWCERT")
 | 
			
		||||
if [ "$NEWCERT_FINGERPRINT" == "" ]
 | 
			
		||||
then
 | 
			
		||||
    echo "no valid new cert found!"
 | 
			
		||||
    exit -1
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#echo "new fingerprint: $NEWCERT_FINGERPRINT"
 | 
			
		||||
@@ -76,16 +75,16 @@ fi
 | 
			
		||||
# Get existing cert info if it exists.  if it doesn't exist, we don't need to
 | 
			
		||||
# check it, we can just deploy.
 | 
			
		||||
 | 
			
		||||
if [ -e $EXISTING_CERT_PATH ]
 | 
			
		||||
if [ -e "$EXISTING_CERT_PATH" ]
 | 
			
		||||
then 
 | 
			
		||||
    EXISTING_CERT=$(cat $EXISTING_CERT_PATH)
 | 
			
		||||
    EXISTING_CERT=$(cat "$EXISTING_CERT_PATH")
 | 
			
		||||
    EXISTING_CERT_FINGERPRINT=$(get_fingerprint "$EXISTING_CERT")
 | 
			
		||||
    EXISTING_CERT_ENDDATE=$(get_enddate "$EXISTING_CERT")
 | 
			
		||||
else
 | 
			
		||||
    # create destination dir if needed
 | 
			
		||||
    if [ ! -d $EXISTING_CERT_DIR ]
 | 
			
		||||
    if [ ! -d "$EXISTING_CERT_DIR" ]
 | 
			
		||||
    then 
 | 
			
		||||
        mkdir -p $EXISTING_CERT_DIR
 | 
			
		||||
        mkdir -p "$EXISTING_CERT_DIR"
 | 
			
		||||
    fi
 | 
			
		||||
    deploy_cert "$NEWCERT" "$NEWKEY" "$NEWCHAIN" "$NEWFULLCHAIN" "$EXISTING_CERT_PATH" "$EXISTING_KEY_PATH" "$EXISTING_CHAIN_PATH" "$EXISTING_FULLCHAIN_PATH"
 | 
			
		||||
    exit 0
 | 
			
		||||
@@ -99,29 +98,23 @@ fi
 | 
			
		||||
# if it is the same, exit normally, this will be the common case
 | 
			
		||||
if [ "$NEWCERT_FINGERPRINT" == "$EXISTING_CERT_FINGERPRINT" ]
 | 
			
		||||
then
 | 
			
		||||
    exit -1
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# check that new cert is newer than current cert
 | 
			
		||||
if [ "$EXISTING_CERT_ENDDATE" \> "$NEWCERT_ENDDATE" ]
 | 
			
		||||
then
 | 
			
		||||
    echo "existing cert expiration is older, exiting"
 | 
			
		||||
    exit -1
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# check that new cert is not expired
 | 
			
		||||
if [ "$NEWCERT_ENDDATE" \< "$TODAY" ]
 | 
			
		||||
then
 | 
			
		||||
    echo "new cert is expired, exiting"
 | 
			
		||||
    exit -1
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# if we made it this far, the cert looks good, replace it
 | 
			
		||||
 | 
			
		||||
deploy_cert "$NEWCERT" "$NEWKEY" "$NEWCHAIN" "$NEWFULLCHAIN" "$EXISTING_CERT_PATH" "$EXISTING_KEY_PATH" "$EXISTING_CHAIN_PATH" "$EXISTING_FULLCHAIN_PATH"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#openssl x509 -in <($VAULT_BIN kv get -field=value /secret/apidb.org/cert.pem) -noout -checkend 8640000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,23 @@
 | 
			
		||||
# Common configuration for acme_vault
 | 
			
		||||
# acme_vault::common
 | 
			
		||||
#
 | 
			
		||||
# This class defines the common configuration for the acme_vault module.
 | 
			
		||||
# It sets up the necessary user, group, home directory, and environment
 | 
			
		||||
# variables for the acme_vault module to interact with Let's Encrypt and
 | 
			
		||||
# HashiCorp Vault for certificate management.
 | 
			
		||||
#
 | 
			
		||||
# @param user The system user for the acme_vault module.
 | 
			
		||||
# @param group The system group for the acme_vault module.
 | 
			
		||||
# @param group_members Additional group members that require access to the certificates.
 | 
			
		||||
# @param home_dir The home directory for the acme_vault user.
 | 
			
		||||
# @param contact_email The email address for Let's Encrypt registration and notifications.
 | 
			
		||||
# @param domains The list of domain names to request certificates for.
 | 
			
		||||
# @param overrides A hash of domain-specific configuration overrides.
 | 
			
		||||
#
 | 
			
		||||
# @param vault_token The authentication token for accessing HashiCorp Vault.
 | 
			
		||||
# @param vault_addr The address of the HashiCorp Vault server.
 | 
			
		||||
# @param vault_bin The path to the Vault binary.
 | 
			
		||||
# @param vault_prefix The prefix for storing certificates in Vault.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class acme_vault::common (
 | 
			
		||||
    $user               = $::acme_vault::params::user,
 | 
			
		||||
    $group              = $::acme_vault::params::group,
 | 
			
		||||
@@ -46,9 +63,9 @@ class acme_vault::common (
 | 
			
		||||
    # that require access to the certs
 | 
			
		||||
 | 
			
		||||
    @group { $group:
 | 
			
		||||
      ensure  => present,
 | 
			
		||||
      system  => true,
 | 
			
		||||
      tag     => 'acme_vault_group',
 | 
			
		||||
      ensure => present,
 | 
			
		||||
      system => true,
 | 
			
		||||
      tag    => 'acme_vault_group',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # include lines similar to this in your own modules to add members to the
 | 
			
		||||
@@ -82,7 +99,7 @@ class acme_vault::common (
 | 
			
		||||
 | 
			
		||||
    # renew vault token
 | 
			
		||||
    cron { 'renew vault token':
 | 
			
		||||
      command => ". \$HOME/.bashrc && $vault_bin token renew > /dev/null",
 | 
			
		||||
      command => ". \$HOME/.bashrc && ${vault_bin} token renew > /dev/null",
 | 
			
		||||
      user    => $user,
 | 
			
		||||
      weekday => 1,
 | 
			
		||||
      hour    => 10,
 | 
			
		||||
@@ -90,4 +107,3 @@ class acme_vault::common (
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,19 @@
 | 
			
		||||
# Configuration for deploying certs in vault to the filesystem
 | 
			
		||||
# acme_vault::deploy
 | 
			
		||||
#
 | 
			
		||||
# This class configures the deployment of certificates from HashiCorp Vault
 | 
			
		||||
# to the filesystem. It sets up the necessary directory structure, scripts,
 | 
			
		||||
# and cron jobs to periodically check for and deploy updated certificates
 | 
			
		||||
# for the specified domains.
 | 
			
		||||
#
 | 
			
		||||
# @param user The system user for the acme_vault module.
 | 
			
		||||
# @param group The system group for the acme_vault module.
 | 
			
		||||
# @param home_dir The home directory for the acme_vault user.
 | 
			
		||||
# @param domains The list of domain names for which certificates will be deployed.
 | 
			
		||||
#
 | 
			
		||||
# @param cert_destination_path The directory where certificates will be deployed on the filesystem.
 | 
			
		||||
# @param deploy_scripts The directory where deployment scripts will be stored.
 | 
			
		||||
# @param restart_method The command to run after certificate deployment (e.g., to restart dependent services).
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class acme_vault::deploy(
 | 
			
		||||
    $user                  = $::acme_vault::common::user,
 | 
			
		||||
    $group                 = $::acme_vault::common::group,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,63 @@
 | 
			
		||||
# params for both common, request, and deploy
 | 
			
		||||
# acme_vault::params
 | 
			
		||||
#
 | 
			
		||||
# This class defines the default parameters for the acme_vault module.
 | 
			
		||||
# It includes settings for the acme user, authentication, staging and production URLs,
 | 
			
		||||
# repository paths, Namecheap configuration, and deployment settings.
 | 
			
		||||
#
 | 
			
		||||
# @param user The system user for the acme_vault module.
 | 
			
		||||
# @param group The system group for the acme_vault module.
 | 
			
		||||
# @param group_members Members of the acme_vault group.
 | 
			
		||||
# @param home_dir The home directory for the acme_vault user.
 | 
			
		||||
# @param contact_email The contact email address for Let's Encrypt notifications.
 | 
			
		||||
# @param domains The list of domain names for which certificates will be requested and managed.
 | 
			
		||||
# @param overrides A list of challenge-alias overrides. Defaults to the domain itself.
 | 
			
		||||
#
 | 
			
		||||
# @param vault_token HashiCorp Vault authentication token.
 | 
			
		||||
# @param vault_addr HashiCorp Vault server address.
 | 
			
		||||
# @param vault_bin Path to the HashiCorp Vault binary.
 | 
			
		||||
# @param vault_prefix The path prefix in Vault where Let's Encrypt secrets are stored.
 | 
			
		||||
#
 | 
			
		||||
# @param staging Whether to use the Let's Encrypt staging environment.
 | 
			
		||||
# @param staging_url Let's Encrypt staging environment API URL.
 | 
			
		||||
# @param prod_url Let's Encrypt production environment API URL.
 | 
			
		||||
#
 | 
			
		||||
# @param acme_revision The revision of the acme.sh script to use.
 | 
			
		||||
# @param acme_repo_path The path to the acme.sh repository.
 | 
			
		||||
# @param acme_script The path to the acme.sh script within the repository.
 | 
			
		||||
#
 | 
			
		||||
# @param namecheap_username Namecheap account username for DNS API.
 | 
			
		||||
# @param namecheap_api_key Namecheap API key.
 | 
			
		||||
# @param namecheap_sourceip The source IP address for Namecheap API requests.
 | 
			
		||||
#
 | 
			
		||||
# @param cert_destination_path The directory where certificates will be deployed on the filesystem.
 | 
			
		||||
# @param deploy_scripts The directory where deployment scripts will be stored.
 | 
			
		||||
# @param restart_method The command to run after certificate deployment (e.g., to restart dependent services).
 | 
			
		||||
#
 | 
			
		||||
class acme_vault::params {
 | 
			
		||||
    # settings for acme user
 | 
			
		||||
    $user       = 'acme'
 | 
			
		||||
    $group      = 'acme'
 | 
			
		||||
    $group_members      = []
 | 
			
		||||
    $home_dir   = '/home/acme_vault'
 | 
			
		||||
    $contact_email = ''
 | 
			
		||||
    $domains     = undef
 | 
			
		||||
    $user           = 'acme'
 | 
			
		||||
    $group          = 'acme'
 | 
			
		||||
    $group_members  = []
 | 
			
		||||
    $home_dir       = '/home/acme_vault'
 | 
			
		||||
    $contact_email  = ''
 | 
			
		||||
    $domains        = undef
 | 
			
		||||
    # overrides is a list of challenge-alias overrides.  It defaults to the domain itself.
 | 
			
		||||
    # see https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode
 | 
			
		||||
    $overrides   = {}
 | 
			
		||||
    $overrides      = {}
 | 
			
		||||
 | 
			
		||||
    # authentication
 | 
			
		||||
    $vault_token = undef
 | 
			
		||||
    $vault_addr  = undef
 | 
			
		||||
    $vault_bin   = "/usr/local/bin/vault"
 | 
			
		||||
    $vault_token    = undef
 | 
			
		||||
    $vault_addr     = undef
 | 
			
		||||
    $vault_bin      = '/usr/local/bin/vault'
 | 
			
		||||
 | 
			
		||||
    $vault_prefix   = '/secret/letsencrypt/'
 | 
			
		||||
 | 
			
		||||
    # whether to use the letsencrypt staging url, set those urls
 | 
			
		||||
    $staging     = false
 | 
			
		||||
    $staging_url = 'https://acme-staging-v02.api.letsencrypt.org/directory'
 | 
			
		||||
    $prod_url    = 'https://acme-v02.api.letsencrypt.org/directory'
 | 
			
		||||
    $staging        = false
 | 
			
		||||
    $staging_url    = 'https://acme-staging-v02.api.letsencrypt.org/directory'
 | 
			
		||||
    $prod_url       = 'https://acme-v02.api.letsencrypt.org/directory'
 | 
			
		||||
 | 
			
		||||
    $acme_revision = 'HEAD'
 | 
			
		||||
    $acme_revision  = 'HEAD'
 | 
			
		||||
    $acme_repo_path = "${home_dir}/acme.sh"
 | 
			
		||||
    $acme_script    = "${acme_repo_path}/acme.sh"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,27 @@
 | 
			
		||||
# Configuration for requesting a cert from letsencrypt, and storing it in vault.
 | 
			
		||||
# acme_vault::request
 | 
			
		||||
#
 | 
			
		||||
# This class configures the certificate request process from Let's Encrypt,
 | 
			
		||||
# and stores the obtained certificates in HashiCorp Vault.
 | 
			
		||||
#
 | 
			
		||||
# @param user The system user for the acme_vault module.
 | 
			
		||||
# @param group The system group for the acme_vault module.
 | 
			
		||||
# @param home_dir The home directory for the acme_vault user.
 | 
			
		||||
# @param contact_email The contact email address for Let's Encrypt notifications.
 | 
			
		||||
# @param domains The list of domain names for which certificates will be requested and managed.
 | 
			
		||||
# @param overrides A list of challenge-alias overrides. Defaults to the domain itself.
 | 
			
		||||
#
 | 
			
		||||
# @param staging Whether to use the Let's Encrypt staging environment.
 | 
			
		||||
# @param staging_url Let's Encrypt staging environment API URL.
 | 
			
		||||
# @param prod_url Let's Encrypt production environment API URL.
 | 
			
		||||
#
 | 
			
		||||
# @param acme_revision The revision of the acme.sh script to use.
 | 
			
		||||
# @param acme_repo_path The path to the acme.sh repository.
 | 
			
		||||
# @param acme_script The path to the acme.sh script within the repository.
 | 
			
		||||
#
 | 
			
		||||
# @param namecheap_username Namecheap account username for DNS API.
 | 
			
		||||
# @param namecheap_api_key Namecheap API key.
 | 
			
		||||
# @param namecheap_sourceip The source IP address for Namecheap API requests.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class acme_vault::request (
 | 
			
		||||
    $user               = $::acme_vault::common::user,
 | 
			
		||||
    $group              = $::acme_vault::common::group,
 | 
			
		||||
@@ -26,11 +47,11 @@ class acme_vault::request (
 | 
			
		||||
    include acme_vault::common
 | 
			
		||||
 | 
			
		||||
    $request_bashrc_template = @(END)
 | 
			
		||||
export TLDEXTRACT_CACHE=$HOME/.tld_set
 | 
			
		||||
export NAMECHEAP_USERNAME=<%= @namecheap_username %>
 | 
			
		||||
export NAMECHEAP_API_KEY=<%= @namecheap_api_key %>
 | 
			
		||||
export NAMECHEAP_SOURCEIP=<%= @namecheap_sourceip %>
 | 
			
		||||
END
 | 
			
		||||
      export TLDEXTRACT_CACHE=$HOME/.tld_set
 | 
			
		||||
      export NAMECHEAP_USERNAME=<%= @namecheap_username %>
 | 
			
		||||
      export NAMECHEAP_API_KEY=<%= @namecheap_api_key %>
 | 
			
		||||
      export NAMECHEAP_SOURCEIP=<%= @namecheap_sourceip %>
 | 
			
		||||
      | END
 | 
			
		||||
 | 
			
		||||
    # variables in bashrc
 | 
			
		||||
    concat::fragment { 'request_bashrc':
 | 
			
		||||
@@ -53,14 +74,14 @@ END
 | 
			
		||||
      owner  => $user,
 | 
			
		||||
      group  => $group,
 | 
			
		||||
      mode   => '0700',
 | 
			
		||||
    } ->
 | 
			
		||||
    file { "${home_dir}/.acme.sh/account.conf":
 | 
			
		||||
    }
 | 
			
		||||
    -> file { "${home_dir}/.acme.sh/account.conf":
 | 
			
		||||
      ensure => present,
 | 
			
		||||
      owner  => $user,
 | 
			
		||||
      group  => $group,
 | 
			
		||||
      mode   => '0600',
 | 
			
		||||
    } ->
 | 
			
		||||
    file_line { ' add email to acme conf':
 | 
			
		||||
    }
 | 
			
		||||
    -> file_line { ' add email to acme conf':
 | 
			
		||||
      path  => "${home_dir}/.acme.sh/account.conf",
 | 
			
		||||
      line  => "ACCOUNT_EMAIL='${contact_email}'",
 | 
			
		||||
      match => '^ACCOUNT_EMAIL=.*$',
 | 
			
		||||
@@ -86,7 +107,7 @@ END
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
      cron { "${domain}_issue":
 | 
			
		||||
        command => "${home_dir}/${domain}.sh",
 | 
			
		||||
        command => ". \$HOME/.bashrc && ${home_dir}/${domain}.sh",
 | 
			
		||||
        user    => $user,
 | 
			
		||||
        weekday => 1,
 | 
			
		||||
        hour    => 11,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user