Saturday, January 24, 2015

What's Puppet and Try the first Puppet Manifest - " Hello Puppet Agent "

I was lucky to be introduced one of DSL(Domain Specific Language), Puppet by my friend Edward. Thus, I went to the Puppet Conference and Training to learn more about the What's DSL since some people said it's a one of key element for CI(Continue Integration)/CD(Continue Deployment or Development) (DevOps). Today, I would like to quick share what's the basic idea about Puppet and show you how to write your first DSL script.

I know it's a little bit weird to introduce writing a puppet code before showing setup the test box. It's because I am still working on finding the easiest way to setup Puppet Master and Agent lab. If you can't wait, try this link to setup your own test box.

Here is my personal preference, I like Q & A since I think it's easier for me to jump into the idea quick. Thus, I share the concept with Q & A format as below.

Again, this is just my way to make a note about what I learn, I think Puppet did great job on documentary. Here are the Puppet Q&A which provide lots of info.

Update:01/31/2015

Installing on Ubuntu

For Debian and Ubuntu, the puppet package contains the Puppet agent, and the puppetmaster package contains the master. 

On the master:

#sudo apt-get install puppet puppetmaster

on the agent:

#sudo apt-get puppet

For the latest version of Puppet you can use the following Puppetlabs repository as update.

Ubuntu Precise:(https://docs.puppetlabs.com/guides/puppetlabs_package_repositories.html)

Update logic: 
  • wget to get deb -> dpkg -i (figure out dependency and install) -> apt-get update (get the new list of avaialbe pckages )
    • #sudo wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb
    • #sudo dpkg -i puppetlabs-release-precise.deb
    • #sudo apt-get update
PS: You can also install Puppet and Facter from source tar file. But Puppet doesn't recommend this approach since make cross-host difficult to maintain / upgrade nodes.

Q:What's different between Shell Script and Puppet Script ?I thought shell or perl can do whatever puppet can do, why we need it ? 

basic logic:

  • wget to get tar.gz -> tar -zxf <*>.tar.gz -> cd <*> -> ./install.rb

A:

Here is what's I surf other blogs and found the answer I prefer ( just my personal preference, please share your opinion with me if you have better explanation ). 

It's because Shell or Perl script are imperative or procedural. They describe how things should be done rather than the desired end state-for. However, Puppet uses a declarative language. With Puppet, it just declares - what the state of their nodes should be, what packages should be installed, what services should be running, and so on. It's easier infrastructure manager's loading and be the idea in cloud era.

In sum, Puppet will only make changes to environment if they are required. ( depends on status or state ). This property is called "idempotency" and is a key feature of Puppet.)

idempotency - depends on state to take action !


Q: What's the Puppet Architecture, how's Puppet work ?



A:

Puppet Architecture includes Master and Agents ( nodes ). The server is called a Puppet "Master", (The Puppet master runs as a "daemon" on a host and contains the configuration required for the specific environment.) The Puppet client software is called an "Agent", (The Puppet agents connect to the Puppet master through an encrypted and authenticated connection using standard SSL, and retrieve or pull any configuration to be applied.) I will demo later.

Importantly, if the Puppet agent has no configuration available or already has the required configuration, Puppet will do nothing. Puppet will only make changes to our environment if they are required. This property is called "idempotency" and is a key feature of Puppet.

Here are the general transaction from agent to master and to other agents. define --> simulate --> enforce --> report, which we call "puppet configuration cycle". We can break it down into puppet life cycle as below, start from steps 1 ~ 6.


1. FACTOR -Agent(deploy)
2. COMPILE - Master (fetch) to git
3. CATELOG - Master -> Agent   (download)
4. APPLY - Agent (others)
5. REPORT - Agent-> Master
6. REPORT PROCESSOR -> Master

PS : factor - "gether info about the host(master) system"


The diagram as below is my favor diagram to show high-level overview of a Puppet configuration run.




Q:How often Puppet Master and Agent Sync ?

A:

General Check 30 Min, The usual practice is to run Puppet as a daemon and have it periodically check with the master to confirm that its configuration is up-to-date or to retrieve any new configuration. By default, the Puppet agent will check the master for new or changed configuration once every 30 minutes. 

However, the agent can check by manual which means trigger by puppet command eg: puppet agent -t or puppet agent --test.

As above, we know time does matter for Puppet. It's important for the time to be accurate on master and agent. SSL connection rely on the "clock" on host being correct. If the clock are incorrect, the connection maybe fail with error indicating that certificates are not trusted. Puppet use NTP (Network Time Protocol) to ensure the host clocks are accurate. The one-time sync ntp command is as below.
#ntpdate bigben.cac.washington.edu


Configuring Puppet

Following questions could provide some basic concept about Puppet Configuring which includes how to configure network and firewall access, and how to start the Puppet master, agents.

Puppet master contains our configuration data, and Puppet agents connect via SSL and pull down the requirement configuration.

The detail can reference Puppet Web Site (https://docs.puppetlabs.com/references/stable/configuration.html)

PS: you can check configuration on master via 
#puppet master --genconfig | less

Q: How does Agent know who is his Master ?

A:

In Puppet Master

Puppet.conf

Via Agent configuration file - puppet.conf (/etc/puppetlabs/puppet/puppet.conf)

The puppet.conf configuration file is constructed much like an INI-style configuration file and divided into sections. Each section configures a particular element of Puppet. 

  • The [agent] section configures the Puppet agent.
  • The [master] section configures the Puppet master binary. 
  • There is also a global configuration section called [main]. All components of Puppet set options specified in the [main] section.

Here is an example, you can see in [Agent] section, I have server tag with master FQDN name (master.puppetlabs.vm). This is how the Agent know who is it's Master.




















Same in master, you could add server value in [main] section
#sudo vim /etc/puppetlabs/puppet/puppet.conf
add
[main]
server=master.puppetlabs.vm


DNS

After that, you need to set up DNS CName either in /etc/hosts file or your DNS configuration




Site.pp

Once we have configured appropriate DNS for Puppet, we need to add the site.pp which holds the basics of configuration items we want to manage. I read some Blog said site.pp is "entry" for Puppet Sync. 

The site.pp tells Puppet where and whats configuration to load for client nodes. It's our first manifest and will be store under /etc/puppetlabs/puppet/manifest/ or /etc/puppet/manifest/. (Site.pp usually be created when installed the Puppet Package)


Firewall

Puppet master run TCP port 8140, it needs to be open on master's firewall, and client must be able to route and connect to master.

#iptables -A INPUT -p tcp -m state --state NEW --dport 8140 -j ACCEPT

Restrict more via limit this to network that require access to Puppet master.

#iptables -A INPUT -p tcp -m state --state NEW -s 192.168.111.128/24 --dport 8140 -j ACCEPT


Start Puppet Master

Now, we are ready and let's start Puppet master.
#service puppetmaster start
or
#puppet master start / restart
#cat /var/log/message - check message

CA:

Generate local CA
#puppet master --verbose --no-daemonize

PS:


  • The log is locate at /var/log/syslog
  • local CA create at /var/lib/puppet/ssl
  • Add --debug option for CA creating to get more verbose debug output from daemon.


Q: How to setup a connection between Agent and Master.

A: 

I think it's nothing special, just like other solution, git, gerrit, jenkins ... etc. Client (Agent) generate request to Server(Master) to request connection with SSH key, Server(Master) review and grant the permission for Client(Agent).

Here I break them down into three major steps.

Request Connection from Agent to Master:

The first time Puppet runs on an Agent node, it will send a Certificate Signing Request (CSR) to the Puppet Master. There has two ways to make master sign agent CSR.

First: 

  1. Agent Trigger from agent commend line 
    1. #puppet agent -t  
    2. #puppet agent --test
  2. master sign CSR request from portal
Second: 

  1. Agent Trigger from agent commend line 
    1. #puppet agent -t  
    2. #puppet agent --test
  2. master sign CSR request 
    1. display: #puppet cert list -a
    2. sign: #puppet cert sign johnnywang.puppetlabs.vm

Before the Master will be able to communicate and control the Agent node, it must sign that particular agent node's certificate.

The request for certificate from Puppet Agent node on the Puppet master node looks like this: 

# puppet agent --no-daemonize --onetime --verbose
or 
# puppet agent -test

PS: you have to use edit the puppet.conf first to add server name as above to let agent know who it should talk to.

puppet.conf
eg:
[Agent]
server:master.puppletlabs.vm

The Agent has created a certificate signing request and a private key to secure our connection. Puppet uses SSL certificates to authenticate connections between the Master and the Agent. The Agent sends the certificate request to the Master and waits for the Master to sign and return the certificate.

At this point, the agent has exited after sending in its Certificate Signing Request (CSR). The agent will need to be rerun to check in and run Puppet after the CSR has been signed by the CA. We can configure puppet agent not to exit, but instead stay alive and poll periodically for the CSR to be signed. This configuration is called "waitforcert" and is generally only useful if we are also auto-signing certificates on the master.

Here we can check what's comment parameter we should use for puppet agent.

# puppet agent --help

* --test:
Enable the most common options used for testing. These are 'onetime','verbose', 'ignorecache', 'no-daemonize', 'no-usecacheonfailure','detailed-exitcodes', 'no-splay', and 'show_diff'.


Complete the Cert Request (sign)

PS: If we want to clear past request, we may us sudo rm -rf /var/lib/puppet/ssl.

At this point, on the 'master' side, we might already have the cert request. We can check cert request from Master use this command.

# puppet cert list -all




To sign a certificate request, the puppetmaster uses the puppet cert sign command, with the 'hostname' of the certificate we want to sign, eg: 

puppet cert sign johnny.puppetlabs.vm

Or you can confirm from Puppet Enterprise Console ( web portal ), in the lab I will provided later you can try either fqdn or ip with browser to login Puppet Web Console, eg:

https://master.puppetlabs.vm 
or
https://192.168.56.102

login: admin@puppetlabs.vm
password: puppetlabs


Client Verify Connection

After Master confirm the connection CSR, Agent can test the sync to verify the connection. Here are the command you can try.

# puppet agent --no-daemonize --onetime --verbose

or
# puppet agent --test

 or
# puppet agent -t





Q:How to write a Puppet DSL (Domain Specific Language) ?

A:

Here, I would like to quick show you how to write, compiler, push to master, then check from report. Before we start let me talk about Puppet "manifest".

Manifest is Puppet's term for files containing configuration information. Manifest files have a suffix of .pp.


Puppet "manifests" are made up of a number of major components:

  • Resources: Individual configuration items
  • Files: Physical files you can serve out to your agents
  • Templates: Template files that you can use to populate files
  • Nodes: Specifies the configuration of each agent
  • Classes: Collections of resources
  • Definitions: Composite collections of resources

Manifest usually includes Resources

Resources
eg:
Resource_type { Resource_Name:
     attribute => value,
}

Each resource is made up of a "Resource_Type" -> Type (what sort of resource is being managed: packages, services, file or cron jobs), "Resource_Name" (the name of the resource)includes a series of "attributes" ("values" that specify the "state" of the resource-for example, whether a service is started or stopped).


  • Type: The type of a resource determines the system component Puppet manages. Some common types are: user, group, file, service and package. A resource declaration always contains the type of resource being managed.
PS: you can try the command as below to list all the resource types.
  # puppet resource -type

eg: if you would like to use user ( type ) to check your status, here is an example.


[root@johnny ~]# puppet resource user johnny

user { 'johnny':

  ensure => 'absent',

}
  • Name(Title): The title of a resource "identifies" an instance of that resource type. The combination of type and title refers to a single unique element managed by puppet, such as a user name 'johnny'. eg: type[title] => user[johnny]
  • Attributes: Each resource supports a list of key value pairs called attributes and value assign with "=>" by attribute These attributes provide a detailed description that Puppet uses to manage the resource. For example, the package 'ssh' should be present. 

Basically Puppet Resource building block or some people said resource types includes, we use ssh key as example

eg:
  • Service - ( ssh service need to be presented )
  • Package - ( ssh Key Name )
  • File - ( ssh Key Location )

update : 4 major key interface between resource and OS.
  • Service
  • Package
  • File
  • User
I used site.pp as my first Puppet DSL demo.


Try 1st puppet DSL demo - fqdn display configuration

I would like to show you how to build your first Puppet Code, there are the demo steps with scree shot for you reference.

First we found site.pp this puppet configuration code in puppetcode/manefest/ folder. We copy to direct under puppetcode/ folder.






























After I copied, I changed to this content.












Here test format, in case you like copy and paste.
node default {
  # This is where you can declare classes for all nodes.
  # Example:
  # class { 'my_class': }
  notify { "Hello Puppet Agent: ${fqdn}": }
}


Puppet Agent Test and Apply Configuration

After we use edit tool (vim or emacs) to update the site.pp content, we will check the syntax via parser, complier in local to review the result, then check-in git and sync between Agent and Master. Finally we can check the Master Console Report to monitor "change:".


Parser ( check syntax )


# puppet parser validate (path)



PS: if your syntax has error, you can see my first try and there has some comment catch the error out to command line.


Compiler Catalog via Apply ( can be unit test )


# puppet apply (path)

Here you can see the complier result --> "Hello Puppet Agent: johnny.puppetlabs.vm" as Catalog .


Add/Commit/Push to Puppet Master

If you setup git directory, cd to git directory with the code, eg: /puppetcode and theck git status.
 # cd puppetcode
# git status

# git add (path)

 


 # git commit -m 'update site.pp commit'

 




 # git push origin master



Run Puppet to trigger Plugin-Sync

# puppet agent --test

 or

# puppet agent -t


Check Agent Change status in Master Console Report 



Reference: 
http://www.bogotobogo.com/DevOps/

No comments:

Post a Comment