Showing posts with label configuration. Show all posts
Showing posts with label configuration. Show all posts

Friday, July 26, 2013

Puppet ~ a beginners concept guide (Part 4) ~ Where is my Data

parts of the "Puppet ~ Beginner's Concept Guide" to read before ~
Part#1: intro to puppet, Part#2: intro to modules, and Part#3: modules much more.

Puppet
beginners concept guide (Part 4)


Where is my Data?

When I started my Puppet-ry, the examples I used to see had all configuration data buried inside the DSL code of manifests, people were trying to use inheritance to push down data. Then got to see a design pattern in puppet manifests keeping out separate parameters manifest for configuration variables. Then came along the External Data lookup via CSV files as a Puppet function. Then with enhancements in puppet and other modules came along more.

Below are few usable to fine ways utilizing separate data sources within your manifests,


Here, we will see usage styles of data for Puppet Manifests, Extlookup CSV, Hiera, Plug-in Facts and PuppetDB.

params-manifest:


It is the very basic way of separating out data from your functionality code, and the preferred way for in-future growing value-set type of data. It will keep it separate from the code since start. Once the requirement is at a level to have varied value to inferred based on environment/domain/fqdn/operatingsystem/[any-facter], it can be extracted to any preferred ways given below and just looked-up here. That would avoid changing the main (sub)module-code.
[ Gist-Set Externalize into Params Manifest: https://gist.github.com/3683955 ]
Say you are providing httpd::git sub-module for httpd module placing a template generated config file using params placed data...
```

File: httpd/manifests/git.pp
it includes the params submodule to access the data

File: httpd/templates/mynode.conf.erb

File: httpd/manifests/params.pp
it actually is just another submodule to only handle data

Use it: run_puppet.sh

```
_

extlookup-csv:


If you think your data would suit to a (key,value) CSV format being extracted to data files.Puppet need to be told the location for CSV files need to be looked up for key, and fetch the value assigned to it in that file.
Names given to these CSV files would matter to Puppet while looking up the values from all present CSV files. Puppet need to be given hierarchy order for these file-names to look for the key and the order could involve variable names.

For E.g. say you have a CSV by name of HOSTNAME, ENVIRONMENT and a common file, with hierarchy specified in respective order too. Then Puppet will first look for the queried Key in CSV by HOSTNAME, if not found looks up in ENVIRONMENT named file and after not finding it there goes looking into common file. If it doesn't find the key in any of those files, it returns the default value if specified in the 'extlookup(key, default_value)' method like this. If there is no default value also, Puppet will raise an exception for no value to return.

[ Gist-Set Externalize into Hierarchical CSV Files: https://gist.github.com/3684010 ]

It's the same example as for params with a flavor of ExtData. Here you'll notice a 'common.csv' external data file providing a default set of values. Then there is also a 'env_testnode.csv' file overriding the only required changed value. Now as in 'site.pp' file, precedence of 'env_%{environment}' file is higher than 'common', the 'httpd::git' would look-up all values first from 'env_testnode.csv' and if not found there would goto 'common.csv'. Hence would end-up overriding 'httpd_git_url' value from 'env_testnode.csv'.
```
```

extlookup() method used here is available as a Puppet Parser Function, you would read more in Part#5 Custom Puppet Plug-Ins on how to create your own functions
_


Hiera is a pluggable hierarchical data storage for Puppet. It was started to provide a better external data storage support than Ext-lookup feature with data formats other than CSV too.

This brings in the essence of ENC for data retrieval without having to write one.

Data look-up happens in a hierarchy provided by configuration with self scope resolution mechanism.

It enables Puppet to fetch data from varied external data sources using it's different backends (like local files, redis, http protocol) which can be added on to if needed.
The 'http' backend in turn enables support for data store from any service (couchdb, riak, web-app or so) to provide data.

File "hiera.yaml" from Gist below is an example of hiera configuration to be placed in puppet's configuration directory. The highlights of this configuration are ":backends:", backend source and ":hierarchy:". Multiple backend can be used at same time, their order of listing mark their order of look-up. Hierarchy configures the order for data look-up by scope.

Then depending on what backend you have added, you need to add their source/config to look-up data at.
Here we can see configuration for using local "yaml", "json" files. Look-up data from Redis server (it will set-up datasets for redis usage for current example) with authentication in place. And looking up data from any "http" service with hierarchy as the ":paths:" value.
You can even use GPG protected data as backend, but that is a bit messy to use.

Placing ".yaml" and ".json" from Gist at intended provider location.
The running "use_hiera.sh" would make you show the magic from this example on hiera.

```Gist
```
[Gist-Set Using Hiera with Masterless Puppet set-up: https://gist.github.com/abhishekkr/6133012 ]
_

plugin-facts:


Every system has its own set of information facter (
http://projects.puppetlabs.com/projects/facter) by default made available to puppet. Puppet also enable DevOps people to set custom facter to be used in modules.
The power of these computed Facters is they can use full ruby-power to use local/remote plain/encrypted data over REST/Database/API/anyway available channel.
These require the power of Puppet Custom Plug-Ins (http://docs.puppetlabs.com/guides/custom_facts.html). The ruby file doing this would go at 'MODULE/lib/puppet/facter' and would get loaded by the 'pluginsync=true' in action.
Way to set a Facter in such Ruby code is just...
my_value = 'all ruby code to compure it'
Facter.add(mykey) do
  setcode do
    my_value
  end
end
.....all the rest of code there need to compute the value to be set, or even key-set.

[Gist-Set Externalize Data receiving as Facter: https://gist.github.com/3684968 ]

Same 'httpd::git' example revamped to use Custom Facter as 
```
```
There is also another way to provide a Facter in Puppet Catalog, that can be done by providing an Environment variable with capitalized Facter name pre-fixed by 'FACTER_' and the value which it's supposed to have.
For E.g. # FACTER_MYKEY=$my_value puppet apply --modulepath=$MODULEPATH -e "include httpd::git"
_

puppetdb:


It's a beautiful addition to Puppet component set. Something that have been missing for long and possibly the thing because of which I delayed this post by half year.
It enables the 'storeconfig' power without the Master, provides a support of trusted DB for infrastructure-related data needs and thus best suited of all.

To set-up 'puppetdb' on a node follow the PuppetLabs has a nice documentation.
To set-up a decent example for master-less puppet mode, follow the given steps

Place the 2 '.conf' and 1 '.yaml' file in Puppet's configuration directory.
The shell script would prepare the node with PuppetDB service for masterless puppet usage scenario.

Puppet config setting storeconfig to 'puppetdb' enables saving of exported resources to it. The 'reports' config their would push the puppet apply reports to the database.
PuppetDB config makes Puppet aware of the host and port to connect database at.
The facts setting on routes.yaml enable PuppetDB to be used in a masterless mode.

```
```

[Gist-Set Using PuppetDB with Masterless Puppet set-up: https://gist.github.com/abhishekkr/6114760 ]

Now running anything say like...
puppet apply -e 'package{"vim": }'
and beautiful to that 'export resources' would work like a charm using PuppetDB.
The puppet.conf accompanied will make reports dumped to PuppetDB as well.

_


There's a fine article on the same by PuppetLabs...

Friday, May 31, 2013

Testing Chaos with Automated Configuration Management solutions


No noise making.

But let's be real, think of the count of community contributed (or mysterious closed-and-sold 3rd Party) services, frameworks, library and modules put to use for managing your ultra-cool self-healing self-reliant scalable Infrastructure requirements. Now with so many cogs collaborating in the infra-machine, a check on their collaboration seems rather mandatory like any other integration test for your in-house managed service. 
After all that was key idea behind having automated configuration management itself.

Now the utilities like Puppet/Chef have been out there accepted and used by dev & ops folks for quite some time now.
But the issue with the initially seen amateur testing styles is it evolved from the non-matching frame of 'Product' oriented unit/integration/performance testing. 'Product' oriented testing focus more on what happens inside the coded logic and less on how user gets affected by product.
Most of the initial tools released for testing logic developed in Chef/Puppet were RSpec/Cucumber inspired Product testing pieces. Now for the major part of installing a package, restarting a service or pushing artifacts these tests are almost non-required as the main functionality for per-say installing package_abc is already tested inside the framework being used.
So coding to "ask" to install package_abc and testing if it has been asked seems futile.

That's the shift. The logic developed for Infrastructure acts as a glue to all other applications created in house and 3rd party. Here in Infrastructure feature development there is more to test for the effect it has on the it's users (software/hardware) and less on internal changes (dependencies and dynamic content). Now the stuff in parentheses here means a lot more than seems... let's get into detail of it.

Real usability of Testing is based on keeping sanctity of WHAT needs to be tested WHERE.


Software/Hardware services that collaborate with the help of Automated Infrastructure logic needs major focus of testing. These services can be varying from the
  • in-house 'Product', that is the central component you are developing
  • 3rd Party services it collaborates with,
  • external services it utilizes for what it doesn't host,
  • operating system that it supports and Ops-knows what not.

Internal changes mainly revolve around
  • Resources/Dependencies getting called in right order and grouped for specific state.
  • It also relates to correct generation/purging of dynamic content, that content can itself range as
    • non-corrupt configuration files generated of a template
    • format of sent configuration data from one Infra-component to another for reflected changes
    • dynamically creating/destroying service instances in case of auto-scalable infrastructure


One can decide HOW, on ease and efficiency basis.


Unit Tests work for the major portion of 'Internal Changes' mentioned before using chefspecrspec-chef, rspec-puppet like libraries are good enough. They can very well test the dependency order and grouping management as well as the different data effect on non-corrupt configuration generation from templates.


Integration Tests in this perspective are a of a bit interesting and evolutionary nature. Here we have to ensure the "glue" functionality we talked about for Software/Hardware service is working properly. These will confirm that every type of required machine role/state can be achieved flawlessly, call them 'State Generation Test'. They also need to confirm the 'Reflected Changes Test' across Infra-component as mentioned in Internal changes.
Now utilities like test-kitchen/docker in collaboration with vagrant, docker, etc. help placing them in your Continuous Integration pipeline. This would even help in testing same service across multiple linux distros if that's the plan to support.
Library 'ServerSpec' is also a little nifty piece to write quick final state check scripts.
Then final set of Integration Testing is implemented in form of Monitoring on your all managed/affecting Infrastructure components. This is the final and ever-running Integration Test.


Performance Tests, yes even they are required for it. Tools like ChaosMonkey enable you to enable your Infra to be self-healing and auto-scalable. Should be load-test noticing dynamic containers count and behavior if auto-scalability is a desired functionality too.

Sunday, August 5, 2012

Puppet ~ a beginners concept guide (Part 3) ~ Modules much more


you might prefer first reading guide Part#1(intro to puppet), & Part#2(intro to modules)
the section after this Part#4(Where is my Data?) discussing how to handle configuration data

Puppet
beginners concept guide (Part 3)

Modules with More

here some time on the practices to prefer while writing most of your modules

[] HowTo Write Good Puppet Modules  
(so everyone could use it and you could use it everywhere)

  • platform-agnostic
    With change in Operating System distro; module also might require difference in package names, configuration file locations, device port names, system commands and more.
    Obviously, it's not expected to test each and every module against each and every distro and get it full-proof for community usage. But what's expected is to use case $operatingsystem{...} statements for whatever distros you can and let the users get notified in case they gotta add something for their distro by fail(""), and might also contribute back..... like following

    case $operatingsystem {
      centos, redhat: {
        $libxml2_development = 'libxml2-devel'
      }
      ubntu, debian: {
        $libxml2_development = 'libxml2-dev'
      }
      default: {
        fail("Unrecognized libxml2 development header package name for your O.S. $operatingsystem")
      }
    }

    ~
  • untangled puppet strings
    You are writing puppet modules. Good chance is you have a client or personal environment to manage for which you had a go at it.
    That means there gonna be your environment specific some client or personal code &/or configuration that is 'for your eyes only'. This will prohibit you from placing any of your module in Community.
    It's wrong on two main fronts. First, you'll end up using so much from OpenSource and give back nothing. Second, your modules will miss on the community update/comment action.
    So, untangle all your modules into atomic service level modules. Further modularize those modules into service puppet-ization requirement. That will be like sub-modules for install, configure, service and whatever more you can extract out. Now these sub-modules can be clubbed together to and we can move bottom-up gradually.
    Now you can just keep your private service modules to yourself, go ahead and use the community trusted and available modules for whatever you can..... try  making minor updates to those and also contribute these updates. Write the others that you don't find out in the wild and contribute those too for community to use, update and improve.
    ~
  • no data in c~o~d~e
    Now when you are delivering 'configuration as a code', adapt the good coding practices applicable in this domain. One of those is keeping data separate than the code, as in no db-name, db-user-name, db-password, etc. details stored directly in the module's manifest intending to create the db-config file.
    There will be a detailed section later over different external data usage involving separate parameter manifest setting up values when included, extlookup loading values from CSVs, puppetDB, hiera data-store and custom facts file to load up key-values.
    ~
  • puppet-lint
    To keep the modules adhere to dsl-syntactic correct and beautiful code writing practice. So the DSL and the community contributors, both find it easy to understand your manifests. It's suggested to have it added to rake default of your project to check all the manifests, ran before every repo-check-in.
    ~
  • do-undo-redo
    It's suggested to have a undo-manifest ready for all the changes made by a module. It mainly comes in handy for infrastructures/situations where creating and destroying a node is not under your administrative tasks or consumes hell lot of time.
    Obviously, in case getting new node is easier..... that's the way to go instead of wasting time in undo-ing all the changes (and also relying on that).
    Those are just there for the dry-days when there is no 'cloud'.
    ~



[] More about Modules  (moreover.....)
Where to get new:http://forge.puppetlabs.com/ is the community-popular home for most of the Puppet Modules.
Where to contribute:
Can manage your public module at GitHub or similar online free repository like 
puppetlabs-kvm.
Then you can push your module to forge.puppetlabs.com.


Saturday, July 28, 2012

DevOps AND 12FactorApp ~ some obsolete & much valid

Why?
Few months ago I came across The Twelve-Factor-App preaching the best practices for building and delivering software. Nothing really new, but a good central place with many good practices for people to refer and compare. Recently I saw some implementation of it in an environment where the basic concerns were already handled and thus the solution implemented was redundant and extra cost. To some level also low-grade.


What?

Actually what 12FactorApp is... it is a good set of ideas around basic set of concerns. The concerns are right, the solutions suggested are situational and the situation is the default/basic setup. With the teams following good DevOps-y practices, they don't turn out to be exactly same.

So to avoid the confusions for more people and foremost saving me the pain of explaining myself at different places in different times for my views against 12FactorApp..... here is what the concerns are and what the solutions turn into when following a proper DevOps-y approach.




What @12FactorApp doesn't suit at all for DevOps-y Solutions

  1. ~
  2. Dependencies
    [+] Obsolete: 'If the app needs to shell out to a system tool, that tool should be vendored into the app.'
    Changed-to: Make your automation configuration management system handle it.
  3. Configurations.
    [+] Obsolete: The twelve-factor app stores config in environment variables changing between deploys w/o changing any code.
    Changed-to: This is not a fine scalable with disaster management based solution. Now configuration management handles the node level deterministic state. The non-developer box level configuration is no more in code.
    [+] Obsolete: The twelve-factor app stores config in environment variables changing between deploys w/o changing any code.
    Changed-to: N
    ow configuration management handles the node level deterministic state. In such a case keeping configurations in a file is much more verifiable, cleaner and broadly available solution. So, there will be no more noise of different environment level configurations in the same configuration file.
  4. ~
  5. Build, Release, Run
    [+] Obsolete: The resulting release contains both the build and config.
    Changed-to: Packaging configuration along-with build makes it dependent of a set environment. Any disaster resistant or scalable architecture would be crippled with it as it requires creating new packages every change. Make your automated configuration management solution intelligent enough to infer required configuration and deploy the build.
  6. ~
  7. ~
  8. Concurrency
    [+] Obsolete: Twelve-factor app processes should never daemonize or write PIDfiles.
    Changed-to: PID files help some automated configuration management solutions to easily identify the 'service' check placed in them. There are operating system level process managers also supporting PIDfiles. Having a pidfile eases up lots of other custom monitoring plug-ins too... and is not a bad practice to have.
  9. ~
  10. ~
  11. ~
  12. ~


Cumulative Correct Concerns 3C@12FactorApp and DevOps-y Solutions

Overall aiming to achieve a easy-to-setup, clean-to-configure, quick-to-scale and smooth-to-update software development ambiance.
The 12 Concerns+Solutions:
  1. Problem: Maintaining Application Source Code
    Solution:
    a.
    Using Version Control Mechanism, if possible Distributed VCS like git. Private hosted (at least private account) code repository.
    b. Unique application~to~repository mapping i.e. single application or independent library's source code in a single repository.
    c. For different versions of same application depend on different commit-stages (not even branches in general cases) of the same code repository.
  2. Problem: Managing Application Dependencies
    Solution:
    a.
     Never manually source compile any dependent library or application. Always depend on the standard PackageManager for the intended platform (like rpm, pkg, gem, egg, npm). If there are no packages available, create one. It's not really difficult. On a standard practice, I'd suggest to utilize something like FPM (may be even fpm-cookery gem if you like), which would give you elasticity of easily changing your platform without worrying for the re-creation of packages. Even creating rpm, gem and other is not too much pain compared to the stability it would bring to infrastructure set-up.
    b. Make your automated configuration management utility ensure all the required dependencies of your application are pre-installed in correct order of correct version with correct required configurations.
    c. The dependency configuration will be specific enough to ensure the usage of the installed & configured dependencies. So in case of compiling binary, use static library linking. If you are loading external libraries, ensure the fixated path. Same configuration management tool can be run even in solo/masterless (no-server) usage mode.
  3. Problem: Configuration in Code, Configuration at all Deploy
    Solution:
    a.
     Ideally no configuration details as in node's IP/Name, credentials, etc. shall not be a part of application's codebase. As if such a configuration file is locally available in developer-box repository, in non-alert & non-gitignore days it might get committed to your repository.
    b. Make your automated configuration management tool generate all these configuration files for a node based on the node-specific details provided to configuration management tool, no the application.
    c. Suggested practice for keeping these configurations with configuration management tool, also require to utilize a proper different data-store from normal configuration statements. Could be in CSVs, Hiera, dedicated parameter's manifest for a tool like Puppet. For a tool like OpsCode's Chef, there is already databag facility available. Wherever available and required the info should be encrypted with a non-repository available secret key.
  4. Problem: Backing Services
    Solution:
    a.
     Whatever other application services are required by application to serve can be included in the 'Backing Services' list. It will be services like data-stores (databases, memory cache and more activesupport), smtp services, etc.
    b. Every information required for these backing services should be configuration details like node-name, credentials, port#, etc. and maintained as a loaded configuration file via configuration management tool.
    c. If it's a highly complex applications broken into several component applications supporting each other, then all other component applications for any component application are also 'Backing Services'.
  5. Problem: Build, Release, Run
    Solution:
    a.
    The development stage code gets pushed to codebase and after passing intended tests should be pushed to Build Stage for preparing deploy-able (compile, include dependencies) code. Should read Continuous Integration process for the better approach at it.
    b. The deploy-able code is packaged ready to deliver in Release Stage and pushed in to the package-manager repositories. The required configuration for execution environment is provided to automated configuration management solution.
    c. Run Stage involves release application package from package-manager and intended system-level configurations via configuration management solution.
  6. Problem: Processes
    Solution:
    a.
    No persistent data related to application shall be kept along-with it. All of user-input & calculated information required for service shall be at the 'Backing Services' available to all the instances of the application of that environment. Helping the application to be stateless.
    b. Get the static assets compiled at 'Build Stage', served via CDN and cached at load balancing server.
    c. Session state data is a good candidate to be stored and retrieved using backing memory powered cache service (like memcache or redis) providing full-blown stateless servers where lossing/killing one and bringing another doesn't impact on user experience.
  7. Problem: Port Binding
    Solution:
    a.
     Applications shouldn't allow any run-time injection to get utilized by 'Backing Services' but instead expose their interaction over any RESTful (or similar) protocol.
    b. In a standard setup, the data/information store/provider opens up a socket and the retriever contacts at the socket with required data transaction protocol. Now this data/information provider can be 'Backing Service' (like db service) or could be the primary application providing information over to a 'Backing Service' (like application server, load balancer).
    c. Either way, they get configured with primary application via automated configuration management by url, port and any other service specific required detail being provided.
  8. Problem: Concurrency
    Solution:
    a.
     Here concurrency is mainly used for highly scalable (on requirement) process model, which is almost equivalent to how used libraries manage internal concurrent processes.
    b. All application & 'Backing Service' processes should be such managed that process count of one doesn't effect another as in say access via load balancer over multiple http processes.
    c. All the processes have a process-type and process-count. There should be a process manager to handle continuous execution of that process with that count. Now it could be ruby rack server to be run with multiple threads on same server, or multiple nodes with nginx serving indecent amount of users via a load balancer.
  9. Problem: Disposability
    Solution:
    a. 
    Quick code & configuration deployment. Configuration Management solution makes sure of the latest (or required stage) application code & configuration changes cleanly & quickly replace the old application exactly as desired.
    b. Application (and 'Backing Services') Architecture shall be elastic, spawning up new nodes under a load-balancer and destroying when the process-load is less must be smooth.
    c. Application's data transactions & task list should be crash-proof. The data & tasks shall be managed to handle the re-schedule of those processes in case of application crash.
  10. Problem: Dev/Prod Parity
    Solution:
    a.
     Keep dev, staging, ..., and production environments as similar as possible.If not in process count and machine nodes count, but necessarily similar on the deployment tasks. Could utilize 'vagrant' in coordination with configuration management solution to get quick production like environments at any development box.
    b. Code manages the application and configuration both, any developer (with considerable system level expertise) could get a hang of configuration management frameworks and manage them. Using 'Backing Services' as mentioned would enable environment based different service providers.
    c. Adapting Continuous Delivery would also ensure no new change in code or configuration breaks the deployment.
  11. Problem: Logs
    Solution:
    a. All staging/production environment will have application and 'Backing Services' promoting its logs to a central (like syslog, syslog-ng, logstash, etc) log hub for archival, if required back-up proof. It can be queried here for analyzing trnds in application performance over past time.
    b.
    The central log solution is not configured within applications but the log solution takes care of what to pick and collect, can even have a look at log routers (fluentd, logplexrsyslog).
    c. Specific log trends can be put to alert everyone effected whenever captured again at Central Log Services (like graylog2, splunk, etc).
  12. Problem: Admin Processes
    Solution:
    a.
     Application level admin processes (like db-migration, specific-case-tasks, debug console, etc.) shall also pick the same code and configuration as the running instances of application.
    b. The admin tasks script related to application shall also ship with application code and evolve with it. As db management rake tasks in RubyOnRails applications, run using 'bundler' to stay pick required Environment related library versions.
    c. Languages with REPL shell (like python) or providing it via separate utility (like 'rails console' for rails) give an advantage to easily debug an environment specific issue (which might me arising due to library versions of that environment, data in-consistency, etc) by directly playing around with the objects seemingly acting as the source of flaw.



As I Always Say

Every Generic Solution is very Specifically Placed.



Tuesday, May 29, 2012

Puppet ~ a beginners concept guide (Part 1)

Someone asked me where to start with Puppet learning. I pointed them at PuppetLabs online doc for Puppet, which is actually nice for a proper understanding. 
But for someone trying to start with Puppet, that documentation is a bit long to read similar to any book. 
I searched for few blogs, but didn't found any content (short but enough, fundamentals but usable) that I was looking for.
____________________________________________________


Puppet
beginners concept guide (Part 1)

[] What  it  is?  When  is  it  required?  (for all new guys, who came here while just browsing internet)
Puppet is an OpenSource automated configuration management framework (which means a tool that knows how to configure all machines to a deterministic state once you provide it the required set of manifests pulling the correct strings).
It's managed at enterprise level by an organization called PuppetLabs (http://puppetlabs.com/).

It is required#1 when you have a hell-lot of machines required to be configured in a similar form.
It is required#2 when you have a infrastructure requirement of dynamic scale-up and scale-down of machines with a pre-determined (or at least metadata-calculated) configuration.
It is required#3 to have a control over all set of configured machines, so a centralized (master-server or repo-based) change gets propagated to all automatically.
And more scenarios come up as you require it.

_____________________________________


[] Quickie.

Install Ruby, Rubygems on your machine where you aim to test it.
$ gem install puppet --no-ri --no-rdoc
Download installers @Windows  @MacOSX ::&:: Docs to installing.

Checking, if it's installed properly and acting good
Now, 'puppet --version' shall give you the version of installed puppet once succeed.
Executing 'facter' and you shall get a list of System Environment related major information.

Have a quick puppet run, this shall create a directory '/tmp/pup' if absent. Creates a file '/tmp/pup/et' with 'look at me' as its content.
{In case of trying out on platforms without '/tmp' location. Like for Windows, change '/tmp' with 'C:/' or so}

$ puppet apply -e "file{'/tmp/pup':
                               ensure => 'directory'}
                             file{ '/tmp/pup/et':
                               ensure => 'present',
                               content => 'look at me',
                               require => File['/tmp/pup']}
                           "

_____________________________________


[] Dumb  usage  structure.
Create huge manifest for your node with all resources & data mentioned in it. Then directly apply that manifest file instead of '-e "abc{.....xyz}"'.

Say if the example above is your entire huge configuration commandment for the node. Copy all that to a file say 'mynode.pp'.
Then apply it similarly like
$ puppet apply mynode.pp

_____________________________________


[] How  it  evolves?

Now, as any application had pluggable library components to be loaded and shared as and when required. Puppet too have a concept of modules. These modules can have manifests, files-serving and more.

Modules can be created in any design preference. Normally it works by having different modules per system component. To entertain different logical configuration states for any given system component (and also keeping it clean) further re-factoring can be done in the modules' manifest dividing it into different scopes.

Taking example of a module for 'apache httpd'. For a very basic library, you might wanna structure your module like

  • a directory base for your module:  <MODULE_PATH>httpd/
  • a directory in module to serve static files:   <MODULE_PATH>/httpd/files
  • static configuration file for httpd:   <MODULE_PATH>/httpd/files/myhttpd.conf
    AccessFileName .acl
  • directory to hold your manifests in module:   <MODULE_PATH>/httpd/manifests/
  • a complete solution manifest:   <MODULE_PATH>/httpd/manifests/init.pp
    class httpd{
      include httpd::install
      include httpd::config
      include httpd::service
    }
  • a manifest just installing httpd:    <MODULE_PATH>/httpd/manifests/install.pp
    class httpd::install {
      package {'httpd': ensure => 'installed'}
    }
  • a manifest just configuring httpd:    <MODULE_PATH>/httpd/manifests/config.pp
    class httpd::config{
      file {'/etc/httpd/conf.d/httpd.conf':
        ensure => 'present',
        source => 'puppet:///modules/httpd/myhttpd.conf'
      }
    }
  • a manifest just handling httpd service:  <MODULE_PATH>/httpd/manifests/service.pp
    class httpd::service{
      service{'httpd': ensure => 'running' }
    }

Now, using it

  $ puppet apply --modulepath=<MODULE_PATH>  -e "include httpd"
would install, custom-configure and start the httpd service.


  $ puppet apply --modulepath=<MODULE_PATH>  -e "include httpd::install"
would just install the httpd service.



________________________________________________________________

Part2: Road to Modules

Wednesday, December 14, 2011

Basics of Powershell ~ empowering Windows Config/Admin Automation

Basics  of  MS Windows Powershell


Introduction
A dotNet framework based scripting language to automate the configuration/administration of Microsoft Windows machine.
Powershell is loaded with several cmdlets (special command-lets) acting as a built-in shell utilities to perform different tasks on Windows machine for performing administrative tasks.


Getting Started
Powershell's cmdlets act upon and return objects as a result of any action taken.
These can be used in combination with traditional Windows services like Registry, Net and more.

To try your hands over powershell, access it at 'Start Menu' > 'Accessories' > 'Windows Powershell';
there you'll get mainly a shell from 'Powershell', and an interactive IDE-like shell 'Powershell ISE'.

Using powershell, cmdlets are the main power-source of this Powershell which are discussed briefly below.....

to get a quick /Hello World/ feel of Powershell, you could try on few next steps
* emulating a dos command 'echo' used to print message at console, 
   command: 
      Write-Host "[get-help write-host] would tell about cmdlet write-host"
* emulating a dos command 'cd' used to change current directory, 
   command: Set-Location C:\Temp
* emulating a dos command 'mkdir' used to create directory, 
   command: New-Item -name "ztemp" -type directory -Force
* emulating a dos command 'dir' used to list items in current directory, 
   command: Get-ChildItem -path C:\Temp
* even the windows 'dir' command can be executed and played with inside powershell.
.....could get a list of cmdlets available in Powershell2.0 ~ http://ss64.com/ps/


[] cmdlets
Command-lets have a specific name format of /'verb'-'noun'/ such as 'Get-ChildItem', 'Get-Help', etc.
To know more about any 'cmdlet' (like using man in linux shell), use
command: Get-Help <_cmdlet_> -detailed

[] A Glimpse of system level SuperUser stuff, as possible on a linux shell
  [+] to get a listing of all System Services,
          command:  Get-Service
  [+] to just get a listing of 'Spooler' named system service, telling its 'name','status' and 'display name'
          command:  Get-Service | Where {$_.name -eq 'Spooler'}
  [+] to get current state of 'Spooler' named system service, whether its running/stopped/paused
          command:  Get-Service | Where {$_.name -eq 'Spooler'} | %{ $_.status }
  [+] to have a Powershell script, check for a system service..... start it if stopped
  $svc_name = "aspnet_state"
  $svc_status = Get-Service | Where {$_.name -eq $svc_name} | %{ $_.status }
  if (-not $svc_status) {
     Write-Host "Error: $svc_name not found"
  }
  elseif ($svc_status -eq "running"){
     Write-Host "status ok $svc_name"
  } else {
     Start-Service $svc_name
  }
  [+] Now you can save the script above as any file say 'start_aspnet.ps1', but to execute it as an external script you would need the local system's Execution Policies to be unrestricted for the script.
       It's not advisable to have it un-restricted all the times, so you could pass on the specific modes along-with the script you desire to be run in un-restricted mode. As below.....
          cmd_prompt:> powershell -executionpolicy unrestricted -file ".\start_aspnet.ps1"
     


helpful links:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa973757(v=vs.85).aspx
http://blogs.msdn.com/b/powershell/
http://thepowershellguy.com/blogs/posh/default.aspx
http://powershell.com/cs/
http://stackoverflow.com/questions/496234/what-tutorial-do-you-recommend-for-learning-powershell