When I initially had issues with Puppet I also looked at “Chef” but my issues with Chef were that it needs a damn site more resources to run plus to download the main chef server component you have to go through a registration page… and while I have no issues with that in itself that is not something that can be automated… so in line with my philosophy for my home lab which is instances must be able to be thrown-up/torn-down on demand or discarded, Chef is in the discarded bucket for now.
Anyway, my initial issues with Puppet were that the repos seemed to be out of sync or shipping conflicting packages. I’m happy to say that has been resolved and installing Puppet from the repos is now a totally hands off experience for me so I will stick with that.
While I do not have enough servers of similar types to use it as a deployment tool for server builds I believe it could be useful for specific tasks, such as ensuring every server has the same set of nagios/nrpe monitoring scripts… rather my my rather ad-hoc method of remembering to push push out new scripts when nrpe reports they are missing :-).
There is a lot of walk throughs on setting up a puppet master server out on the web, mainly for Ubuntu but a few for CentOS as well.
As my setup is mainly Fedora based and I am only looking into it rather than commiting to it as a solution I decided to use a test environment easily able to be rebuilt as needed; in this case my OpenStack home lab environment.
My deployment is a throw-up/tear-down solution for testing (after all that is what cloud instances are for) in my OpenStack test lab using a simple heat template; allowing me to create all the servers with one openstack command and to delete all the servers simply by deleting the stack from the dashboard. The deployment heat template creates a “puppet” server and a “agenttest” server.
After deploying the heat pattern I have a working “puppet” host running puppetserver with the agenttest server registered with it. The agent can register as I configured the puppetserver to automatically accept agent cert registration requests so there is no need for any manual intervention to accept a certificate (as that would defeat the point of automatically deploying the stack in a hands off way using heat patterns).
[root@puppet ~]# puppet cert list --all + "agenttest.mdickinson.dyndns.org" (SHA256) 4D:23:9E:97:77:7C:13:4D:CA:00:42:3B:8F:1A:A6:AB:26:35:A5:B4:D0:FC:B0:A5:3C:08:A2:F1:E7:55:36:FA + "puppet.mdickinson.dyndns.org" (SHA256) 71:84:87:19:DF:90:F7:52:14:67:F2:FE:FA:C1:0A:E4:1B:33:DC:27:E3:41:8B:0D:0D:0E:0D:AB:20:50:88:82 (alt names: "DNS:puppet", "DNS:puppet.mdickinson.dyndns.org") [root@puppet ~]#
If you want to use the heat pattern you will need to note
- change the keypair to one you use
- change the network names to ones you use
- change the image name from CentOS-7-x86_64-GenericCloud-1704.qcow2 to whatever you called your copy of the CentOS7 cloud image
- change the availability_zone used for both servers, most users would use the default “nova” but for my home lab I had to create a custom availability zone to ensure I always had resources available
- the custom flavor centos7-puppet-min is a minimum of 3Gb memory, 3Gb swap, 8Gb root disk (centos7 cloud image needs 8Gb root disk)
- the custom flavor centos7-min is a minimum of 1Gb memory, 3Gb swap, 8Gb root disk (centos7 cloud image needs 8Gb root disk)
- in each instance definition I hard code the address of my external router (192.168.1.1) as an addition to the resolv.conf file so the instances can resolve internet addresses for the package installs, if you are not in a ‘home lab’ you will need to change that in both server instances
My OpenStack lab environment is currently OpenStack Ocata version, installed from the RDO repository via packstack with the main customisation being additional compute nodes. All the nodes are running CentOS7.
The heat template is run simply by (a user with heat_admin authority of course) “openstack stack create –template puppet_master_centos7.yaml puppet_testing” which will create a stack named puppet_testing with the following resources
- create a custom security group to be used by the instances
- create a “puppet” server on my tenant internal network and
- install packages I always need for network troubleshooting
- assign a password of “password” to root for troubleshooting from the console (bad I know)
- install the puppetserver packages
- make lots of customisations, including to automatically accept cert requests
- start the puppetserver
- assign a floating ip-address to the instance, also primarily for troubleshooting (for getting into it without the console)
- create a “agentest” server on my tenant internal network and
- install packages I always need for network troubleshooting
- assign a password of “password” to root for troubleshooting from the console (bad I know)
- install the puppet-agent packages
- ensure the puppet-agent is running
- change sshd configuration to allow root to login directly, also for troubleshooting so from the “puppet” instance I can login to the agent instance via the internal tenant network without having to copy ssh keys onto the puppet instance
And you have a running and working puppetserver instance to play with with running agent server to test rules against.
When you are done with it just use the dashboard Project/Orchestration/Stacks screen to delete the stack, and all instances and the decurity group will be deleted, and the floating ip released.
Anyway, the template
[root@region1server1 heat_stacks(keystone_mark)]# cat puppet_master_centos7.yaml heat_template_version: 2016-10-14 description: > Install a puppet master server and agent server, Custom Flavor notes, CentOS7 cloud image needs a minimum 8Gb disk image for each instance, puppetserver instance needs at least 3Gb memory and 3Gb swap, agent needs 1Gb memory 2Gb swap, the floating ip on puppet server is not recomended but I find it usefull to get into the test stack quickly bypassing a normal tenant gateway server. parameters: key_name: type: string label: Key Name description: Name of key-pair to be used for compute instance default: marks-keypair-ocata root_password: type: string label: Root User Password description: Password to be used for root user hidden: true default: password constraints: - length: { min: 6, max: 8 } description: Password length must be between 6 and 8 characters. - allowed_pattern: "[a-zA-Z0-9]+" description: Password must consist of characters and numbers only. net: description: name of network used to launch instance. type: string default: tenant-mark-10-0-3-0 subnet: description: name of subnet within network used to launch instance. type: string default: tenant-mark-10-0-3-0-subnet1 public_network: description: name of the public network to associate floating ip from. type: string default: ext-net-192-flat resources: puppet-server: type: OS::Nova::Server properties: name: puppet key_name: { get_param: key_name } image: CentOS-7-x86_64-GenericCloud-1704.qcow2 flavor: centos7-puppet-min security_groups: [{ get_resource: puppet_security_group }] availability_zone: compute-pool networks: - network: { get_param: net } user_data: str_replace: template: | #!/bin/bash echo "Customising system image..." # For troubleshooting use a known password for console login echo "$ROOTPSWD" | passwd root --stdin timedatectl set-timezone Pacific/Auckland wc_notify --data-binary '{"status": "SUCCESS"}' # echo "nameserver 192.168.1.1" >> /etc/resolv.conf sync yum -y install telnet iputils psmisc sync # # enable the puppetlabs repo and install puppetserver rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm yum -y install puppetserver # # In a VM with 3Gb memory and two cores the puppetserver takes a long # time to start and generate its key; the startup will fail and loop # trying to start and being killed by systemd forever unless the startup # timeout values are changed. They must be changed in two configuration # files as systemd will use the lowest of either value set. # Also change puppetserver memory allocation from 2Gb to 1Gb cp /etc/sysconfig/puppetserver /tmp/puppetserver_sysconfig cat /tmp/puppetserver_sysconfig | sed -e's/-Xms2g -Xmx2g/-Xms1g -Xmx1g/' | sed -e's/START_TIMEOUT=300/START_TIMEOUT=1200/' > /etc/sysconfig/puppetserver cp /usr/lib/systemd/system/puppetserver.service /tmp cat /tmp/puppetserver.service | sed -e's/TimeoutStartSec=300/TimeoutStartSec=1200/' > /usr/lib/systemd/system/puppetserver.service cp /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf /tmp # there are issues with letting legacy auth remain defaulted to true cat /tmp/puppetserver.conf | sed -e's/#use-legacy-auth-conf: false/use-legacy-auth-conf: false/' > /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf systemctl daemon-reload # # create an empty default manifest file touch /etc/puppetlabs/code/environments/production/manifests/site.pp # # try and resolve timeout issues # MID added, makes no difference but documented as making no change echo "# MID added" >> /etc/puppetlabs/puppet/puppet.conf echo "http_connect_timeout = 2m" >> /etc/puppetlabs/puppet/puppet.conf echo "http_read_timeout = 5h" >> /etc/puppetlabs/puppet/puppet.conf echo "filetimeout = 5m" >> /etc/puppetlabs/puppet/puppet.conf # Normally you would not autosign, but should make testing easier echo "autosign = true" >> /etc/puppetlabs/puppet/puppet.conf # # puppet command is not in path until logoff/logon, add for next three commands export PATH=$PATH:/opt/puppetlabs/bin/puppet puppet resource package hiera ensure=installed puppet resource package facter ensure=installed puppet resource package rubygem-json ensure=installed # # Start puppetserver, during startup it will generate its ssl cert systemctl enable puppetserver # # systemctl start puppetserver WAIT, DO NOT START IT YET # KNOWN BUG: https://tickets.puppetlabs.com/browse/SERVER-248 # that there is no intention of fixing # If ipv6 is enabled puppet will only listen on ipv6... centOS7 enables # ipv6 be default, even if the interface network-scripts/ifcfg-xxx has # ipv6init="no". Disable ipv6 in order to use puppet if you have any # agents that use ipv4 echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf sysctl -p # # Now it should start OK systemctl start puppetserver # logger "End of puppetserver cloud init scripted install" echo "...end of install" exit 0 # ... done params: $ROOTPSWD: { get_param: root_password } floating_ip: type: OS::Neutron::FloatingIP properties: floating_network: {get_param: public_network} association: type: OS::Neutron::FloatingIPAssociation properties: floatingip_id: { get_resource: floating_ip } port_id: {get_attr: [puppet-server, addresses, {get_param: net}, 0, port]} puppet-agent-test: type: OS::Nova::Server properties: name: agenttest key_name: { get_param: key_name } image: CentOS-7-x86_64-GenericCloud-1704.qcow2 flavor: centos7-min security_groups: [{ get_resource: puppet_security_group }] availability_zone: compute-pool networks: - network: { get_param: net } user_data: str_replace: template: | #!/bin/bash echo "Customising system image..." # For troubleshooting use a known password for console login echo "$ROOTPSWD" | passwd root --stdin timedatectl set-timezone Pacific/Auckland wc_notify --data-binary '{"status": "SUCCESS"}' # # Servers with only private ips I allow password logins # (or all the ssh keys would have to be copied to all servers # in the private network that might want to logon to this server). cd /etc/ssh cat sshd_config | sed -e 's/PasswordAuthentication no/PasswordAuthentication yes/' > sshd_config.new mv sshd_config sshd_config.old mv sshd_config.new sshd_config chmod 644 sshd_config service sshd restart # Additional nameserver for resolving external download sites on first install boot echo "nameserver 192.168.1.1" >> /etc/resolv.conf sync yum -y install telnet iputils psmisc sync # # It takes along time for the puppet master to install packages and configure itself. # As soon as the agent starts it will send a cert request to the puppet server, # we must wait until the 'puppet' server has been fully configured as part of the stack build # before we start the agent that will immediately try to connect to it to elimate # the puppet server being available as the cause of the idletimeout errors seen in # puppet server logs. echo "*** Agent startup is delaying for 20mins to allow puppet master to fully configure ***" logger "*** Agent startup is delaying for 20mins to allow puppet master to fully configure ***" sleep 20m # # Then install the puppet agent packages rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm yum -y install puppet-agent # to resolve timeout issues echo "http_read_timeout = 5h" >> /etc/puppetlabs/puppet/puppet.conf /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true # echo "use 'puppet cert list' and 'puppet cert sign' on the puppet server to register this agent" echo "this agent will have generated the cert request to the pupper server when the agent started." echo "...end of install" exit 0 # ... done params: $ROOTPSWD: { get_param: root_password } puppet_security_group: type: OS::Neutron::SecurityGroup properties: description: Ports needed for a puppet master server. name: puppet-security-group rules: [ {remote_ip_prefix: 0.0.0.0/0, protocol: tcp, port_range_min: 22, port_range_max: 22}, {remote_ip_prefix: 0.0.0.0/0, protocol: tcp, port_range_min: 80, port_range_max: 80}, {remote_ip_prefix: 0.0.0.0/0, protocol: tcp, port_range_min: 443, port_range_max: 443}, {remote_ip_prefix: 0.0.0.0/0, protocol: tcp, port_range_min: 8140, port_range_max: 8140}, {remote_ip_prefix: 0.0.0.0/0, protocol: icmp}] outputs: instance_private_ip_puppet: description: Private IP address of puppet server value: { get_attr: [puppet-server, networks, {get_param: net}, 0] } instance_public_ip_puppet: description: Public IP address of agent server value: { get_attr: [puppet-server, networks, {get_param: net}, 1] } instance_keypair: description: SSH Key-Pair to be used to access the instances value: { get_param: key_name } instance_rootpw: description: Root password for both servers value: { get_param: root_password } instance_private_ip_testagent: description: Private IP address of puppetagent test server value: { get_attr: [puppet-agent-test, networks, {get_param: net}, 0] }