Multiple repositories

Since you are already considering r10k, I think you are on the right track.
I took a look at the installer code, and while I am not 100% sure what those options do, I think they create a local git repo which will be automatically deployed to environments if commits are pushed to it’s branches. From what I understand, this is not what you are looking for.
With r10k, you have one branch in the control repo per environment, and each of them can have it’s own Puppetfile with the modules for that environment. Automatic deployment could be realized via some pipeline functionality by, for example, by SSH-ing into the Foreman system and running r10k.

Thank you for your feedback, it really helped me. I looked at it again with a co-worker and we think that a repository can be set up in /etc/puppetlabs/code/environments/ and submodules (i.e. subrepos) within it from the various control_repos in Gitlab and Azure Devops as described here: Git Tools - Submodules. r10k would not be a must at first, but only a possible later option.

What isn’t clear to me yet: I initially imported a repo and then had all classes visible in Foreman. If implemented with git submodules, a local git pull cron job would ensure synchronization of the file system in code/environments/repo/*.

But of course I cannot carry out a manual import into Foreman every time, a class was edited in a git commit. How can I trigger Foreman to reimport the environments after the commits?

The repos/submodules look like this in my head:

└── environments (gitlab main repo)
     ├── team1 (git submodule to gitlab repo of team1)
     ├── team2 (git submodule to azure devops repo of team2)
     ├── team3 (git submodule to azure devops repo of team3)
     ├── team4 (git submodule to azure devops repo of team4)
     └── team5 (git submodule to azure devops repo of team5)

For how to trigger a reimport of the Puppet classes, you can either go with hammer (via the hammer proxy import-classes command) or you can use an API call via the POST /api/smart_proxies/:id/import_puppetclasses or POST /api/smart_proxies/:smart_proxy_id/environments/:id/import_puppetclasses endpoints (See /apidoc on your Foreman server for more infos).
I you realize pulling the repos via cron, I would suggest implementing one of these methods in the same cron job.
You could also make this a part of some CI/CD Pipeline process if you use something like that, but that would require to make the actual git checkout also part of that process.

1 Like

Thank you very much, your description seems to be the solution for me.
But for now I am stuck when I go to Configure → Puppet ENC → Environments → Import → puppet.services.example.com. I get this Error:

ERF12-2749 [ProxyAPI::ProxyException]: Unable to get environments from Puppet ([RestClient::Forbidden]: 403 Forbidden) for proxy https://puppet.services.example.com:8443/puppet

I removed /etc/puppetlabs/code and recreated code from the gitlab repo containing git submodules as follows:

code
├── environments
│   ├── common
│   ├── production
│   ├── webprod
│   └── webtest

I also ran foreman-installer with option --puppet-server-environments-recurse

That error sounds like some sort of authentication/certificate issue between Foreman and the smart-proxy.
Are there any errors in /var/log/foreman-proxy/proxy.log?

you were right, I had to edit settings.yml in /etc/foreman-proxy to include all hostnames in the trusted-hosts option (localhost, puppet.services.example.com etc.).

I installed hammer:

foreman-cli                              3.8.0-1+ubuntu2004
ruby-hammer-cli                          3.8.0-1+ubuntu2004
ruby-hammer-cli-foreman                  3.8.0-1+ubuntu2004
ruby-hammer-cli-foreman-puppet           0.0.6-1
ruby-hammer-cli-foreman-remote-execution 0.2.3-1+ubuntu2004
ruby-hammer-cli-foreman-ssh              0.0.3
ruby-hammer-cli-foreman-tasks            0.0.19-1+ubuntu2004
ruby-hammer-cli-foreman-templates        0.2.0-2
ruby-hammer-cli-foreman-webhooks         0.0.4-1

and I can see the binary with which hammer: /usr/bin/hammer

when I run hammer proxy import-classes I get this error:

Warning: An error occured while loading module hammer_cli_foreman_templates.
Error: No such sub-command ‘proxy’.

This is foreman 3.8.0 on Ubuntu 20.04 and Puppet Opensource 7.27.0

additionally I have set in /etc/hammer/cli_config.yml the different ssl keys to /etc/puppetlabs/puppet/ssl/certs etc. but hammer tells me these are wrong (although working in foreman ui). I also use letsencrypt for apache proxy. I also tried to use the letsencrypt key to no avail.

This error is weird. The proxy subcommand should be part part of the “core” hammer-cli-foreman package. Can you paste the full output of hammer --help? I just checked the code to see if the command was recently renamed, but it does not look like it.

This should be unrelated and lead do a different error if it was a problem. Have you set up the letsencrypt cert through foreman-installer? If so, I would assume the installer should also set the settings for hammer.

Output of hammer --help:

hammer --help

Warning: Couldn’t load configuration file /etc/hammer/cli_config.yml: (): did not find expected key while parsing a block mapping at line 2 column 1.
NOTE: Gem.gunzip is deprecated; use Gem::Util.gunzip instead. It will be removed on or after 2018-12-01.
Gem.gunzip called from /usr/lib/ruby/vendor_ruby/unicode/display_width/index.rb:5.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server’s CA certificate installed on your system.

The following configuration option were used for the SSL connection:
ssl_ca_file = /etc/letsencrypt/live/puppet.services.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server’s CA certificate installed on your system.

The following configuration option were used for the SSL connection:
ssl_ca_file = /etc/letsencrypt/live/puppet.services.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_puppet.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server’s CA certificate installed on your system.

The following configuration option were used for the SSL connection:
ssl_ca_file = /etc/letsencrypt/live/puppet.services.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_remote_execution.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server’s CA certificate installed on your system.

The following configuration option were used for the SSL connection:
ssl_ca_file = /etc/letsencrypt/live/puppet.services.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_ssh.
Warning: An error occured while loading module hammer_cli_foreman_tasks.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server’s CA certificate installed on your system.

The following configuration option were used for the SSL connection:
ssl_ca_file = /etc/letsencrypt/live/puppet.services.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_templates.
Usage:
hammer [OPTIONS] SUBCOMMAND [ARG] …

Parameters:
SUBCOMMAND Subcommand
[ARG] … Subcommand arguments

Subcommands:
defaults Defaults management
full-help Print help for all hammer commands
prebuild-bash-completion Prepare map of options and subcommands for Bash completion
shell Interactive shell

Options:
–[no-]use-defaults Enable/disable stored defaults. Enabled by default
–autocomplete VALUE Get list of possible endings
–csv Output as CSV (same as --output=csv)
–csv-separator VALUE Character to separate the values
–fetch-ca-cert VALUE Fetch CA certificate from server and exit
–interactive BOOLEAN Explicitly turn interactive mode on/off
–no-headers Hide headers from output
–output ENUM Set output format
Possible value(s): ‘base’, ‘table’, ‘silent’, ‘csv’, ‘yaml’, ‘json’
–output-file VALUE Path to custom output file
–show-ids Show ids of associated resources
–ssl-ca-file VALUE Configure the file containing the CA certificates
–ssl-ca-path VALUE Configure the directory containing the CA certificates
–ssl-client-cert VALUE Configure the client’s public certificate
–ssl-client-key VALUE Configure the client’s private key
–ssl-with-basic-auth Use standard authentication in addition to client certificate authentication
–verify-ssl BOOLEAN Configure SSL verification of remote system
–version Show version
-c, --config VALUE Path to custom config file
-d, --debug Show debugging output
-h, --help Print help
-p, --password VALUE Password to access the remote system
-q, --quiet Completely silent
-r, --reload-cache Force reload of Apipie cache
-s, --server VALUE Remote system address
-u, --username VALUE Username to access the remote system
-v, --[no-]verbose Be verbose (or not). True by default

Option details:
Here you can find option types and the value an option can accept:

BOOLEAN One of true/false, yes/no, 1/0
DATETIME Date and time in YYYY-MM-DD HH:MM:SS or ISO 8601 format
ENUM Possible values are described in the option’s description
FILE Path to a file
KEY_VALUE_LIST Comma-separated list of key=value.
JSON is acceptable and preferred way for such parameters
LIST Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for such parameters
MULTIENUM Any combination of possible values described in the option’s description
NUMBER Numeric value. Integer
SCHEMA Comma separated list of values defined by a schema.
JSON is acceptable and preferred way for such parameters
VALUE Value described in the option’s description. Mostly simple string

Alright, so maybe it is a certificate issue after all.
How did you set up the let’s encrypt certs for Foreman? Did you change configs by hand or did you use foreman-installer?
Here you can find a “proper” solution on how to set the certificates correctly. I have not tested this myself, but I would assume that also updates the hammer config to use the correct certificate files.

I did not set anything for hammer via foreman-installer. I assume the hammer stuff is the foreman::cli section in the foreman-answers.yaml file? This section does not look very configured for me:

foreman::cli:
  foreman_url:
  version: installed
  manage_root_config: true
  username:
  password:
  use_sessions: false
  refresh_cache: false
  request_timeout: 120
  ssl_ca_file:
foreman::cli::ansible: false
foreman::cli::azure: false
foreman::cli::discovery: false
foreman::cli::google: false
foreman::cli::kubevirt: false
foreman::cli::openscap: false
foreman::cli::puppet: {}
foreman::cli::remote_execution: {}
foreman::cli::ssh: {}
foreman::cli::tasks: {}
foreman::cli::templates: false
foreman::cli::webhooks: {}

Would it work to edit this file and run foreman-installer without any option?
Although I cannot see any cert related stuff for hammer.

ah there is ssl_ca_file
sorry, there is indead some cert related stuff :slight_smile:

I would suggest to use the foreman-installer command from the post I linked instead of modifying the answers file by hand. Foreman-installer takes care of those things for you and remembers your answers for the future (in that exact answers file). Modifying by hand will skip sanity checks and the likes. The foreman-cli configs there are (probably) configured to use a default value if not specified, which will probably point to some foreman variables.

I used foreman-installer as in your linked example.
But how can I get the correct setting for the line

foreman::cli 
...
...
  ssl_ca_file:

?
I am sure this should be the /etc/puppetlabs/puppet/ssl path and not the letsencrypt path. letsencrypt is correct only for server_ssl_* stuff. But e.g. foreman-proxy would not work with the LE cert, only with the cert in /etc/puppetlabs/puppet/ssl

I am 99% sure this setting needs to be the letsencrypt CA, since it is the CA file that hammer will check the cert provided by Foreman’s API against. So if your Foreman web interface and API are using a letsencrypt cert, you need hammer to use the letsencrypt ca file.
A loot at the Puppet module the installer uses confirms this: https://github.com/theforeman/puppet-foreman/blob/master/manifests/cli.pp#L55-70
It is using the value of --foreman-server-ssl-chain from the installer.

Thank you for your patience :wink:

my value of --foreman-server-ssl-chain is /etc/letsencrypt/live/puppet.services.example.com/chain.pem

When I use this command syntax:


hammer --ssl-ca-file /etc/letsencrypt/live/puppet.service.example.com/chain.pem --ssl-ca-path /etc/letsencrypt/live/puppet.service.example.com --ssl-client-cert /etc/letsencrypt/live/puppet.service.example.com/cert.pem --ssl-client-key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem

I get this output:


Warning: Couldn't load configuration file /etc/hammer/cli_config.yml: (<unknown>): did not find expected key while parsing a block mapping at line 2 column 1.
NOTE: Gem.gunzip is deprecated; use Gem::Util.gunzip instead. It will be removed on or after 2018-12-01.
Gem.gunzip called from /usr/lib/ruby/vendor_ruby/unicode/display_width/index.rb:5.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server's CA certificate installed on your system.

The following configuration option were used for the SSL connection:
  ssl_ca_path = /etc/letsencrypt/live/puppet.service.example.com
  ssl_ca_file = /etc/letsencrypt/live/puppet.service.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server's CA certificate installed on your system.

The following configuration option were used for the SSL connection:
  ssl_ca_path = /etc/letsencrypt/live/puppet.service.example.com
  ssl_ca_file = /etc/letsencrypt/live/puppet.service.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_puppet.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server's CA certificate installed on your system.

The following configuration option were used for the SSL connection:
  ssl_ca_path = /etc/letsencrypt/live/puppet.service.example.com
  ssl_ca_file = /etc/letsencrypt/live/puppet.service.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_remote_execution.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server's CA certificate installed on your system.

The following configuration option were used for the SSL connection:
  ssl_ca_path = /etc/letsencrypt/live/puppet.service.example.com
  ssl_ca_file = /etc/letsencrypt/live/puppet.service.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_ssh.
Warning: An error occured while loading module hammer_cli_foreman_tasks.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could't read SSL client certificate /etc/letsencrypt/live/puppet.service.example.com/cert.pem.
Could't read SSL client key /etc/letsencrypt/live/puppet.service.example.com/fullchain.pem.
Could not load the API description from the server: SSL certificate verification failed
Make sure you configured the correct URL and have the server's CA certificate installed on your system.

The following configuration option were used for the SSL connection:
  ssl_ca_path = /etc/letsencrypt/live/puppet.service.example.com
  ssl_ca_file = /etc/letsencrypt/live/puppet.service.example.com/chain.pem

Make sure the location contains an unexpired and valid CA certificate for https://puppet.services.example.com.

Warning: An error occured while loading module hammer_cli_foreman_templates.

This is my /etc/hammer/cli_config.yml:


:ui:
  :interactive: true
  :history_file: '~/.hammer/history'
:watch_plain: false
:reload_cache: false
:log_level: 'debug'
:verbosity: 2
:completion_cache_file: '~/.cache/hammer_completion.json'
  :ssl_ca_path: '/etc/letsencrypt/live/puppet.services.example.com/chain.pem'
  :verify_ssl: true
  :ssl_client_cert: '/etc/letsencrypt/live/puppet.services.example.com/cert.pem'
  :ssl_client_key: '/etc/letsencrypt/live/puppet.services.example.com/privkey.pem'
  :ssl_with_basic_auth: false

Firstly, the various SSL options in your config should be untder a ssl section. I guess you forgot to un-comment the :ssl: line. That’s probably why hammer tells you it cannot load it’s config file.
If that does not resolve the issue (which I would guess, because the let’s encrypt certs probably are not issued for client auth), try removing the ssl_client_cert, ssl_client_key and ssl_with_basic_auth values from your hammer config and see if that works. I don’t know how to set up certificate based auth for hammer, but in the default configuration, hammer uses HTTP basic auth, with the username and password stored in ~/.hammer/cli.modules.d/foreman.yml ( if I remember correctly).

You were right, :ssl: was commented.
After uncommenting this line, I still get the same cert errors, but now it mixes the /etc/puppetlabs/puppet/ssl and the /etc/letsencrypt paths although in the hammer conf only letsencrypt paths are available …
When I set verify_ssl = false, I no more receive cert auth errors, but now it complains about tlsv1 stuff and finally tells me: No such sub-command proxy

This is the complete output for hammer proxy import-classes:

NOTE: Gem.gunzip is deprecated; use Gem::Util.gunzip instead. It will be removed on or after 2018-12-01.
Gem.gunzip called from /usr/lib/ruby/vendor_ruby/unicode/display_width/index.rb:5.
Could not load the API description from the server: 
SSL_read: tlsv1 alert unknown ca
  - is the server down?
  - was 'foreman-rake apipie:cache' run on the server when using apipie cache? (typical production settings)
Warning: An error occured while loading module hammer_cli_foreman.
Could not load the API description from the server: 
SSL_read: tlsv1 alert unknown ca
  - is the server down?
  - was 'foreman-rake apipie:cache' run on the server when using apipie cache? (typical production settings)
Warning: An error occured while loading module hammer_cli_foreman_puppet.
Could not load the API description from the server: 
SSL_read: tlsv1 alert unknown ca
  - is the server down?
  - was 'foreman-rake apipie:cache' run on the server when using apipie cache? (typical production settings)
Warning: An error occured while loading module hammer_cli_foreman_remote_execution.
Could not load the API description from the server: 
SSL_read: tlsv1 alert unknown ca
  - is the server down?
  - was 'foreman-rake apipie:cache' run on the server when using apipie cache? (typical production settings)
Warning: An error occured while loading module hammer_cli_foreman_ssh.
Warning: An error occured while loading module hammer_cli_foreman_tasks.
Could not load the API description from the server: 
SSL_read: tlsv1 alert unknown ca
  - is the server down?
  - was 'foreman-rake apipie:cache' run on the server when using apipie cache? (typical production settings)
Warning: An error occured while loading module hammer_cli_foreman_templates.
Error: No such sub-command 'proxy'.

Running foreman-rake apipie:cache makes no difference.

Commenting these lines in /etc/hammer/cli_config.yml (as you suggested) causes hammer-cli to work now:

 :ssl_client_cert:
 :ssl_client_key:
 :ssl_with_basic_auth:
1 Like