Ask Your Question
0

Including a common apache::vhost on all servers via Hiera/YAML

asked 2016-04-27 10:38:50 -0500

bschonecker gravatar image

updated 2016-06-09 15:16:07 -0500

I have about 300 Apache servers that all need a common virtual host setup for our monitoring and load balancing application.

Currently, I use a wrapper class to extract the vhost information from Hiera and that all works fine. What I need to do now is include a standard vhost definition that all servers get. I'm using Hiera and YAML to achieve this but I've found myself repeating the same lines of YAML code over and over in the individual hosts' YAML files. What I'd like to do is have the standard vhost definition in the global.yaml file and an "include" of some sort in the <hostname.example.com>.yaml file that references the global.yaml.

Here's what I have in global.yaml:

# MOST but not all servers have 'cache-<servername>.example.org' VHOST
--- 
vhosts:
  cache-admin01.example.org: 
    docroot: '/var/www/html/cache'

Here's what I have in admin01.example.org.yaml: --- vhosts: admin01.healthplan.com: docroot: '/var/www/html/admin01'

This is what hiera returns:

[root@admin01 bschone]# hiera --hash vhosts
{"admin01.example.org"=>{"docroot"=>"/var/www/html/admin01"},
"cache-admin01.example.org"=>{"docroot"=>"/var/www/html/cache"}}

This is exactly what I want - the admin01.example.org.yaml and the global.yaml entries for vhosts are merged.
Success so far. However, not ALL my servers need "cache" virtual host. A great majority do but not all so I can't use the hiera_has on the vhost as it is. The way I need it to work is for the admin01.example.org.yaml to lookup via "%{hiera('')}" from inside the admin01.example.org.yaml file itself. Here's an example of what I think it should work:

global.yaml:

---
global-cache:
  cache-admin01.example.org:
  docroot: '/var/www/html/cache'

in admin01.example.org.yaml:

---
vhosts:
  admin01.example.org:
    docroot: '/var/www/html/admin01'
  cache-admin01.example.org:
    "%{hiera_hash('global_cache')}"  # <-- This is where I'd like to 'reference' the global.yaml value.

I would think that "%{hierahash('globalcache')}" would do a lookup to global.yaml but that doesn't seem to be happening. Here's what hiera returns:

[root@admin01 bschone]# hiera --hash vhosts
{"admin01.example.org"=>{"docroot"=>"/var/www/html/admin01"},
 "cache-admin01.example.org"=>""}

Unfortunately, hiera doesn't "look up" my global_cache entry and I get an empty return for 'cache-admin01'. I realize that this example won't work for any other server but 'admin01' but I'll cross that bridge when I come to it.

Is there any way to do what I want in hiera (or another method). I think this should work but it's my inexperience with hiera at this level that's causing me fits.

cat /etc/hiera.yaml

---
:backends:
  - yaml
:hierarchy:
  - defaults
  - "%{clientcert}"
  - "%{environment}"
  - global

:yaml:
# datadir is empty here, so hiera uses its defaults:
# - /var/lib/hiera on *nix
# - %CommonAppData%\PuppetLabs\hiera\var on Windows
# When specifying a datadir, make sure the directory exists.
  :datadir:

#:merge_behavior: deeper
edit retag flag offensive close merge delete

Comments

Could you show us what your hiera.yaml file looks like?

schowdhury gravatar imageschowdhury ( 2016-04-27 11:38:17 -0500 )edit

Question updated...

bschonecker gravatar imagebschonecker ( 2016-04-27 12:55:12 -0500 )edit

It's a bit difficult to read your posts because you are showing your code in normal format. You can try displaying your code using the code block formatting. Aside from that I think your code should work if you comment out the 'everyonevhost' line from <hostname.example.com>.yaml.

schowdhury gravatar imageschowdhury ( 2016-04-27 15:16:15 -0500 )edit

I have [hopefully] updated this thread with appropriate markdown tags.

bschonecker gravatar imagebschonecker ( 2016-05-25 13:15:58 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2016-05-25 19:27:55 -0500

DarylW gravatar image

updated 2016-05-30 15:43:37 -0500

I think the answer to your question is hiera_hash. There are three ways to access hiera.

  1. hiera() - Allows you to pick the top 'value' for your key from your hierarchy
  2. hiera_array() - Lets you make an array out of all values found in your hierarchy for a single key
  3. hiera_hash() - Lets you 'merge' together the hashs for a single key, with duplicate values favoring the top of the hierachy

There is a superb example here The hiera_hash example is actually about most webservers having a similar vhost configuration... exactly what you are looking for!

-------------- EDIT ----------------------- You should do something like the following, but rename everyone_vhost to something different...

global.yaml:

everyone_vhost:
  cache.%{::fqdn}:
    servername: cache.%{::fqdn}
    docroot: '/var/www/html/example.org'
    docroot_owner: 'webmaster'
    docroot_group: 'webmaster'
    ip: *

in hostname.example.com.yaml:

 everyone_vhost:  cache.%{:fqdn}:
docroot_owner: 'someotherwebmaster'

If in your profile, you reference hierahash('everyonevhost'), it should resolve to the following hash..

  { 'cache.hostname.example.com' => {
    'servername' => 'cache.hostname.example.com',
    'docroot' => '/var/www/html/example.org',
    'docroot_owner' => 'someotherwebmaster',
    'docroot_group' => 'webmaster',
    'ip' => '*',
    }
  }

The value of docroot_owner should be overriden with the value givine in your hostname.example.com.yaml file, and the rest of the values should be filled in from the global.yaml everyone_hash

edit flag offensive delete link more

Comments

Yeah, I've tried that. Unfortunately, 'referencing' global::everyone_vhosts doesn't work in this situation. Hiera seems to convert the hash into a string so the Apache module complains. The apache module (wrapper script) expects array of hashes (hashed array?) so this fails.

bschonecker gravatar imagebschonecker ( 2016-05-27 07:39:46 -0500 )edit
1

@bschonecker Add how it fails to your answer with useful logs and your code that is doing the lookup. I'd guess your new hash isn't equivalent to the old. Merging hashes with hiera_hash or after the fact with merge() from stdlib should be straightforward.

ramindk gravatar imageramindk ( 2016-05-29 20:35:53 -0500 )edit

you need the variable named the same for hiera_hash to do it's magic. If you want to specifically read in two hashes and combine them, you could use the deep_merge function( It's either in puppet or stdlib). Not sure if you can pass that to create_resources

DarylW gravatar imageDarylW ( 2016-05-30 15:29:14 -0500 )edit

I reread your above answer, you are referencing 'everyone_vhosts' inside of hiera, you shouldn't do that. You should leave it undefined in your profile, and if you need to replace a value, only define that value you want to override. then in your profile, read in hiera_hash('everyone_vhost')

DarylW gravatar imageDarylW ( 2016-05-30 15:33:16 -0500 )edit

I have made major edits to the question because after re-reading it, I wasn't clear as to my intentions.

bschonecker gravatar imagebschonecker ( 2016-06-09 15:16:50 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-04-27 10:38:50 -0500

Seen: 378 times

Last updated: Jun 09 '16