{"id":1875,"date":"2023-11-17T22:46:48","date_gmt":"2023-11-18T03:46:48","guid":{"rendered":"https:\/\/enterpriseadmins.org\/blog\/?p=1875"},"modified":"2023-11-17T22:46:48","modified_gmt":"2023-11-18T03:46:48","slug":"keeping-linux-up-to-date-with-aria-automation-config","status":"publish","type":"post","link":"https:\/\/enterpriseadmins.org\/blog\/virtualization\/keeping-linux-up-to-date-with-aria-automation-config\/","title":{"rendered":"Keeping Linux up to date with Aria Automation Config"},"content":{"rendered":"\n<p>I have several persistent Windows &amp; Linux VMs in my lab.  The Windows VMs get their OS updates via Windows Server Update Service (WSUS) managed by group policy.  This works pretty consistently and keeps everything current.  The Linux VMs are a mix of Photon OS 4 and 5 as well as Ubuntu 20.04, and every time I ssh in I see a notification that updates are available.  If I have a few minutes I&#8217;ll usually take the opportunity to get current&#8230; but these VMs could run for weeks without an interactive ssh login, leaving some security risk on the table.<\/p>\n\n\n\n<p>In my lab I have an Aria Automation Config (formerly known as Salt Stack Config) appliance that I&#8217;ll use occasionally.  It has functionality to run scheduled jobs on managed minions, but I&#8217;ve not taken time to set that up &#8212; until today.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inventory<\/h2>\n\n\n\n<p>The first step I wanted to tackle was an inventory of patches that are required for the various endpoints.  Looking around at available out-of-box functions in Aria Automation Config, I found a command <code>pkg.list_upgrades<\/code> that looked promising.  I ran it against all minions and then looked at the resulting out.  The raw return is available as JSON, so I imported it into Powershell (<code>Get-Content timestamp-return.json | ConvertFrom-Json<\/code>) and started looking at the details.  There is an item for each minion and that item contains a <code>return<\/code> note property which looks similar to this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$json&#91;0].return |fl\r\n\r\n\r\nlibpq5          : 11.22-0+deb10u1\r\npython-urllib3  : 1.24.1-1+deb10u2\r\npython3-urllib3 : 1.24.1-1+deb10u2<\/code><\/pre>\n\n\n\n<p>For my purposes I&#8217;m mostly interested in the count of the <code>return<\/code> items&#8230; the number of packages that need to be updated.  To find these counts, I came up with the following oneliner:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$json | Select-Object minion_id, has_errors, @{N='NumUpdates';E={($_.return | Get-Member -Type NoteProperty | Measure-Object).Count}} | ?{$_.NumUpdates -ne 0} |Sort-Object minion_id\n\nminion_id                              has_errors NumUpdates\r\n---------                              ---------- ----------\r\ndr-extdns-21.lab.enterpriseadmins.org       False          8\r\nh135-linux-01.lab.enterpriseadmins.org      False          7\r\nh135-linux-02.lab.enterpriseadmins.org      False        105\r\nnet-cont-21.lab.enterpriseadmins.org        False         75\r\nnet-wanrtr-01.lab.enterpriseadmins.org      False         46\r\nraspberrypi                                 False          3\r\nsaltmaster                                  False         34\r\nsvcs-cont-21.lab.enterpriseadmins.org       False         61<\/code><\/pre>\n\n\n\n<p>Looking at this list I can see that my updates are all over the place, some are fairly current, others are way off.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Apply the Updates<\/h2>\n\n\n\n<p>To apply updates to Linux, I first created a small state file called <code>updates\/os.sls<\/code> and entered the following contents:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>update_pkg:\r\n  pkg.uptodate:\r\n    - refresh: True<\/code><\/pre>\n\n\n\n<p>I ran applied this state to an Ubuntu box, and once complete logged in to check the system to make sure it was fully patched.  Running an <code>apt list upgradable<\/code> I found some missing updates.  I re-applied the state file, hoping that another round of updates would get me current, but the same updates were still missing.  After doing some searching online, I found that I needed to include an extra line in my state file to include <code>dist_upgrade<\/code> so version 2 looked like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>update_pkg:\n  pkg.uptodate:\n    - refresh: True\n    - dist_upgrade: True<\/code><\/pre>\n\n\n\n<p>Applying this revised state to the Ubuntu VM got it all matched up with the <code>apt list upgradable<\/code> results. I then expanded this task to a few more VMs, but ran into a problem when applying the revised version 2 of the state to a Photon OS VM.  The results of the Photon VMs showed an error message of: <code>No such option: --dist_upgrade<\/code> , which is the additional line I had just added to get better patching coverage.<\/p>\n\n\n\n<p>I could have created two different state files, jobs, and associated schedules &#8212; one to target Ubuntu and another for Photon, using both of the above versions of the state file, but I wanted to have a more generic \/ shared update process for all Linux systems.  Instead of creating duplicate states\/jobs, I decided to add some <code>if<\/code> logic to my state file.  The out of the box <code>sse\/apache\/init.sls<\/code> showed a perfect example of how to accomplish this.  For the final version of my state file, I look to see if the OS is Photon, and if so apply the <code>pkg.uptodate<\/code> without the <code>dist_upgrade<\/code> flag, otherwise I do include it.  The syntax looks like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>update_pkg:\r\n{% if grains&#91;'os'] == 'VMware Photon OS' %}\r\n  pkg.uptodate:\r\n    - refresh: True\r\n{% else %}\r\n  pkg.uptodate:\r\n    - refresh: True\r\n    - dist_upgrade: True\r\n{% endif %}<\/code><\/pre>\n\n\n\n<p>Now when I apply this state to a Linux VM, it updates both system types without error.  The sample apache state also has some <code>else if<\/code> examples if we need to get more specific in the future&#8230; for example, pulling in Windows patching with the same state.  For now, the single <code>if\/else<\/code> works just fine.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Report on the Updates<\/h2>\n\n\n\n<p>The output from the above job which applies the <code>updates\/os.sls<\/code> state returns a JSON body similar to our first reporting task.  I tried importing this JSON into Powershell to see what sort of interesting reporting was available.  One set of data that we can see is the list of packages which were updated, including the old &amp; new version numbers.  Here is an example from one minion:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$json&#91;0].return.'pkg_|-update_pkg_|-update_pkg_|-uptodate'.changes\r\n\r\n\r\napt                          : @{new=2.0.10; old=2.0.6}\r\nufw                          : @{new=0.36-6ubuntu1.1; old=0.36-6}\r\nbolt                         : @{new=0.9.1-2~ubuntu20.04.2; old=0.8-4ubuntu1}\n&lt;list truncated for readability><\/code><\/pre>\n\n\n\n<p> For comparison to the initial report of which updates were needed, I also wanted to summarize what was updated to see if my counts were similar.  The following output is from an initial test run on a subset of minions: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$json | Select-Object Minion_id, has_errors, @{N='NumPkgs';E={ ($_.full_ret.return.'pkg_|-update_pkg_|-update_pkg_|-uptodate'.changes| Get-Member -Type NoteProperty | Measure-object).Count }} | Sort-Object minion_id\r\n\r\nminion_id                              has_errors NumPkgs\r\n---------                              ---------- -------\r\ndr-extdns-21.lab.enterpriseadmins.org       False       8\r\nh135-linux-01.lab.enterpriseadmins.org      False       7\r\nh135-linux-02.lab.enterpriseadmins.org      False     105\r\nnet-wanrtr-01.lab.enterpriseadmins.org      False      46<\/code><\/pre>\n\n\n\n<p>Comparing the above output to the initial report we can see that all available updates were applied.<\/p>\n\n\n\n<p>I&#8217;ve since created a schedule to run each of these jobs on a regular basis.  For now, the inventory job will run daily so that I can see\/track progress, and the update job will run every weekend.  Hopefully the next time I ssh into a Linux VM I won&#8217;t be presented with a laundry list of required updates. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have several persistent Windows &amp; Linux VMs in my lab. The Windows VMs get their OS updates via Windows Server Update Service (WSUS) managed by group policy. This works pretty consistently and keeps everything current. The Linux VMs are &hellip; <a href=\"https:\/\/enterpriseadmins.org\/blog\/virtualization\/keeping-linux-up-to-date-with-aria-automation-config\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9,4],"tags":[],"class_list":["post-1875","post","type-post","status-publish","format-standard","hentry","category-lab-infrastructure","category-virtualization"],"_links":{"self":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1875","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/comments?post=1875"}],"version-history":[{"count":2,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1875\/revisions"}],"predecessor-version":[{"id":1886,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1875\/revisions\/1886"}],"wp:attachment":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/media?parent=1875"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/categories?post=1875"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/tags?post=1875"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}