<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/salt/</id>
  <link href="https://www.endpointdev.com/blog/tags/salt/"/>
  <link href="https://www.endpointdev.com/blog/tags/salt/" rel="self"/>
  <updated>2014-03-27T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Puppet, Salt, and DevOps (a review of the MountainWest DevOps conference)</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/03/puppet-salt-and-devops-review-of/"/>
      <id>https://www.endpointdev.com/blog/2014/03/puppet-salt-and-devops-review-of/</id>
      <published>2014-03-27T00:00:00+00:00</published>
      <author>
        <name>Spencer Christensen</name>
      </author>
      <content type="html">
        &lt;p&gt;Last week I attended the MountainWest DevOps conference held in Salt Lake City, Utah. This was a one day conference with a good set of presenters and lightning talks. There were several interesting topics presented, but I’ll only review a few I wanted to highlight.&lt;/p&gt;
&lt;h3 id=&#34;i-serve-no-master&#34;&gt;I Serve No Master!&lt;/h3&gt;
&lt;p&gt;Aaron Gibson of &lt;a href=&#34;http://www.adaptivecomputing.com/&#34;&gt;Adaptive Computing&lt;/a&gt; discussed a very common problem with Puppet (and other configuration management systems): they work well in the scenario they were designed for but what about when the situation isn’t typical? Aaron had a situation where developers and QA engineers could instantiate systems themselves via OpenStack, however the process for installing their company’s software stack on those VMs was inconsistent, mostly manual, and took many hours. One of the pain points he shared, which I related to, was dealing with registering a puppet node with a puppet master—​the sometimes painful back and forth of certificate issuing and signing.&lt;/p&gt;
&lt;p&gt;His solution was to remove the puppet master completely from the process. Instead he created a bash wrapper script to execute a workflow around what was needed, still using puppet manifests on each system but run locally. This wrapper tool, called “Builder”, relies on property files to customize the config and allow the script to manage different needs. This new script allowed them to keep using puppet to manage these self-serve OpenStack servers gaining the benefits of consistency and removing manual setup steps, providing the ability to automate installs with Jenkins or other tools. But it freed them from having to use a puppet master for nodes that were disposable. It also helped to reduce software install time from 12 hours down to a 11 minutes.&lt;/p&gt;
&lt;p&gt;His Builder tool is still an internal only tool for his company, but he discussed some next steps he would like to add, including better reporting and auditing of executions. I pinged him after the conference on twitter and mentioned that &lt;a href=&#34;http://rundeck.org/&#34;&gt;Rundeck&lt;/a&gt; might be a good fit to fill that gap. I used Rundeck for 2 years at my last job, integrating nicely with other automation tools and providing reporting and auditing as well as access control of arbitrary jobs.&lt;/p&gt;
&lt;h3 id=&#34;automating-cloud-factories-and-the-internet-assembly-line-with-saltstack&#34;&gt;Automating cloud factories and the internet assembly line with SaltStack&lt;/h3&gt;
&lt;p&gt;Tom Hatch of &lt;a href=&#34;https://saltstack.com/&#34;&gt;Salt Stack&lt;/a&gt; spoke about Salt as an automation and remote execution platform. I’ve done quite a bit of work with Salt recently with a client and so I was pretty familiar with Salt. But one thing that he mentioned I didn’t know was that Salt was originally designed as a Cloud management tool, not necessarily a configuration management tool. However in the course of time configuration management became a higher priority for the Salt dev team to focus on. Tom mentioned that recently they have been working on Cloud management tools again—​providing integration with Rackspace, AWS, xen, and more. I’ll have to dig more into these tools and give them a try.&lt;/p&gt;
&lt;h3 id=&#34;how-i-learned-to-stop-worrying-and-love-devops&#34;&gt;How I Learned to Stop Worrying and Love DevOps&lt;/h3&gt;
&lt;p&gt;Bridget Kromhout of 8thBridge (since aquired by &lt;a href=&#34;https://web.archive.org/web/20150322054413/https://www.fluid.com/news/fluid-acquires-social-crm-platform-8thbridge&#34;&gt;Fluid&lt;/a&gt;) spoke on the culture of DevOps and her journey from a corporate, strictly siloed environment to a small start-up that embraced DevOps. One of the first things she brought up that was different was the focus and approach to goals of each organization. In an organization where Ops teams are strictly separate from Developers, they often butt heads and have a limited vision of priorities. Each focuses on the goals of their own team or department, and have little understanding of the goals of the other departments. This leads to an adversarial relationship and culture of not caring much about different teams or departments.&lt;/p&gt;
&lt;p&gt;In contrast, the organization that embraces DevOps as a culture will see to it that Ops and Devs work together on whatever solution best reaches the goals of the whole organization. In doing so, barriers will have to be questioned. Any “special snowflake” servers/applications/etc. that only one person knows and can touch can’t exist in this culture. Instead, any unique customizations need to be minimized through automation, documentation (sharing knowledge), and reporting/monitoring. This doesn’t mean root access for all—​but it means reducing barriers as much as possible. Good habits from the Ops world to keep include: monitoring, robustness, security, scaling, and alerting.&lt;/p&gt;
&lt;p&gt;The main pillars of DevOps are: culture, automation, measurement, and sharing. Culture is important and can be supportive or rejecting of the other pillars. Without a culture in the organization that supports DevOps, it will fizzle back into siloed “us vs. them” enmity.&lt;/p&gt;
&lt;p&gt;Thanks to all the presenters and those that put on the conference. It was a great experience and I am glad I attended.&lt;/p&gt;
&lt;h3 id=&#34;links&#34;&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/biggiemac/mtnwest_prez/blob/master/I%20Serve%20No%20Master!%20-%20Aaron%20Gibson%20-%20MTN%20West%20DevOps%202014.pdf&#34;&gt;Slide deck for Aaron Gibson: “Serve No Master!”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.slideshare.net/bridgetkromhout/how-i-learnedtostopworryingandlovedevops201403&#34;&gt;Slide deck for Bridget Kromhout: DevOps culture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
    <entry>
      <title>Setting a server role in Salt (comparing Puppet and Salt)</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/12/setting-server-role-in-salt-comparing/"/>
      <id>https://www.endpointdev.com/blog/2013/12/setting-server-role-in-salt-comparing/</id>
      <published>2013-12-23T00:00:00+00:00</published>
      <author>
        <name>Spencer Christensen</name>
      </author>
      <content type="html">
        &lt;p&gt;There are many ways to solve a given problem, and this is no truer than with configuration management. Salt (&lt;a href=&#34;https://saltstack.com&#34;&gt;https://saltstack.com&lt;/a&gt;) is a fairly new tool in the configuration management arena joining the ranks of Puppet, Chef, and others. It has quickly gained and continues to grow in popularity, boasting its scalable architecture and speed. And so with multiple tools and multiple ways to use each tool, it can get a little tricky to know how best to solve your problem.&lt;/p&gt;
&lt;p&gt;Recently I’ve been working with a client to convert their configuration management from Puppet to Salt. This involved reviewing their Puppet configs and designs and more-or-less mapping them to the equivalent for Salt. Most features do convert pretty easily. However, we did run into something that didn’t at first/assigning a role to a server.&lt;/p&gt;
&lt;p&gt;We wanted to preserve the “feeling” of the configs where possible. In Puppet they had developed and used a convention for using some custom variables in their configs to assign an “environment” and a “role” for each server. These variables were assigned in the node and role manifests. But in Salt we struggled to find a similar way to do that, but here is what we learned.&lt;/p&gt;
&lt;p&gt;In Puppet, once a server’s “role” and “environment” variables were set, then they could be used in other manifest files to select the proper source for a given config file like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    file    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#34;/etc/rsyslog.conf&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            source  =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;puppet:///rsyslog/rsyslog.conf.$hostname&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;puppet:///rsyslog/rsyslog.conf.$system_environment-$system_role&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;puppet:///rsyslog/rsyslog.conf.$system_role&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;puppet:///rsyslog/rsyslog.conf.$system_environment&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;puppet:///rsyslog/rsyslog.conf&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ensure  =&amp;gt; present,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            owner   =&amp;gt; &amp;#34;root&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            group   =&amp;gt; &amp;#34;root&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            mode    =&amp;gt; &amp;#34;644&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Puppet will search the list of source files in order and use the first one that exists. For example, if $hostname = &amp;lsquo;myniftyhostname&amp;rsquo; and $system_environment = &amp;lsquo;qa&amp;rsquo; and $system_role = &amp;lsquo;sessiondb&amp;rsquo;, then it will use rsyslog.conf.myniftyhostname if it exists on the Puppet master, or if not then use rsyslog.conf.qa-sessiondb if it exists, or if not then rsyslog.conf.sessiondb if it exists, or if not then rsyslog.conf.qa if it exists, or if not then rsyslog.conf.&lt;/p&gt;
&lt;p&gt;In Salt, environment is built into the top.sls file, where you match your servers to their respective state file(s), and can be used within state files as {{ env }}. Salt also allows for multiple sources for a managed file to be listed in order and it will use the first one that exists in the same way as Puppet. We were nearly there; however, setting the server role variable was not as straight forward in Salt.&lt;/p&gt;
&lt;p&gt;We first looked at using Jinja variables (which is the default templating system for Salt), but soon found that setting a Jinja variable in one state file does not carry over to another state file. Jinja variables remain only in the scope of the file they were created in, at least in Salt.&lt;/p&gt;
&lt;p&gt;The next thing we looked at was using Pillar, which is a way to set custom variables from the Salt master to given hosts (or minions). Pillar uses a structure very similar to Salt’s top.sls structure- matching a host with its state files. But since the hostnames for this client vary considerably and don’t lend themselves to pattern matching easily, this would be cumbersome to manage both the state top.sls file and the Pillar top.sls file and keep them in sync. It would require basically duplicating the list of hosts in two files, which could get out of sync over time.&lt;/p&gt;
&lt;p&gt;We asked the salt community on #salt on Freenode.net how they might solve this problem, and the recommended answer was to set a custom grain. Grains are a set of properties for a given host, collected from the host itself- such as, hostname, cpu architecture, cpu model, kernel version, total ram, etc. There are multiple ways to set custom grains, but after some digging we found how to set them from within a state file. This meant that we could do something like this in a “role” state file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# sessiondb role
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# {{ salt[&amp;#39;grains.setval&amp;#39;](&amp;#39;server_role&amp;#39;,&amp;#39;sessiondb&amp;#39;) }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;include:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - common
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then within the common/init.sls and postgres/init.sls state files we could use that server_role custom grain in selecting the right source file, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/etc/rsyslog.conf:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  file.managed:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - source:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - salt://rsyslog/files/rsyslog.conf.{{ grains[&amp;#39;host&amp;#39;] }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - salt://rsyslog/files/rsyslog.conf.{{ env }}-{{ grains[&amp;#39;server_role&amp;#39;] }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - salt://rsyslog/files/rsyslog.conf.{{ grains[&amp;#39;server_role&amp;#39;] }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - salt://rsyslog/files/rsyslog.conf.{{ env }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - salt://rsyslog/files/rsyslog.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - mode: 644
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - user: root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - group: root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This got us to our desired config structure. But like I said earlier, there are probably many ways to handle this type of problem. This may not even be the best way to handle server roles and environments in Salt, if we were more willing to change the “feeling” of the configs. But given the requirements and feedback form our client, this worked fine.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
