avatarBill WANG

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3801

Abstract

des. For instance, disabling specific <a href="https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/provisioner">provisioners</a> becomes easier by commenting them out, saving both build and test time.</li></ul><h1 id="4405">Solution diagram</h1><p id="70bc">Here is the updated diagram, with the shared component centralized in the middle, serving both AWS and Azure.</p><figure id="2e1a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Oo9eWvHAU2lZUyADmyu-xQ.png"><figcaption><a href="https://excalidraw.com/#json=wcnAiyTnkWsk-WHoL6IlD,tSxa74dCQMQPKV5uBvbmsA">https://excalidraw.com/#json=wcnAiyTnkWsk-WHoL6IlD,tSxa74dCQMQPKV5uBvbmsA</a></figcaption></figure><p id="2dfc">You can refer <a href="https://excalidraw.com/#json=wcnAiyTnkWsk-WHoL6IlD,tSxa74dCQMQPKV5uBvbmsA">this link </a>to view above diagram on excalidraw</p><p id="933b">Git code’s folders for reference</p><div id="955e"><pre>Git repo root <span class="hljs-keyword">for</span> codes of image builder |- CIS <span class="hljs-comment"># put all CIS hardening scripts, share between AWS and Azure</span> |- AL2023 |- RHEL8 |- RHEL9 |- Win2019 |- Win2022 |-Scripts <span class="hljs-comment"># put all install scripts, share between AWS and Azure</span> |-Linux |- CloudWatchAgent.sh |- SplunkAgent.sh |- CrowdStrike.sh |- CIS-hardening.sh |- AzureVMAgent.sh |-Windows |- CloudWatchAgent.ps1 |- SplunkAgent.ps1 |- CrowdStrike.ps1 |- CIS-hardening.ps1 |- AzureVMAgent.ps1 |- Pipelines <span class="hljs-comment"># Azure DevOps Pipeline supports multiple pipeline files</span> |- aws-pipeline.yaml |- azure-pipeline.yaml |- PackerTemplates <span class="hljs-comment"># Prepare packer template for each linux and Windows system</span> |- rhel8-aws.pkr.hcl |- rhel9-aws.pkr.hcl |- al2023-aws.pkr.hcl |- amaz2-aws.pkr.hcl |- win2019-aws.pkr.hcl |- rhel8-azure.pkr.hcl |- rhel9-azure.pkr.hcl |- win2019-azure.pkr.hcl </pre></div><p id="2c53">Four main folders in the source codes</p><ul><li><b>CIS</b> — put all CIS hardening scripts, group for different OS systems, share between AWS and Azure</li><li><b>Scripts</b> — put all install and configuration scripts, write for both Linux Bash script and Windows PowerShell scripts, share between AWS and Azure</li><li><b>Pipelines</b> — two pipelines for both AWS and Azure</li><li><b>PackerTemplates</b> — Prepare packer templates for each linux and Windows system on AWS and Azure</li></ul><p id="8fb3">Explanation and general rules</p><ul><li>No agent binary packages should be saved in git repository directly. Copy from AWS s3 bucket or Azure Storage Account. This is for some agent install packages, which can’t be downloaded from public links directly</li><li>If you have software active codes, license IDs, recommends to save to AWS SSM parameter/secret manager, or Azure Key/Vault.</li><li>When image building, all configuration files and binary packages, could be copied to same destination, for exmaple, <b>C:\temp</b> (Windows) or<b> /tmp</b> (Linux) , in the build instances</li><li>All commands should not be directly put in packer templates, always called from shell or powershell script. With this way, same scripts can be shared between AWS and Azure image Builds. Remeber to put a comments in the script, so we know the build stages. For example</li></ul><div id="2210"><pre><span class="hljs-comment"># Packer code:</span>

provisioner <span class="hljs-string">"powershell"</span> { scripts = [<span class="hljs-string">"Scripts/SplunkAgent.ps1"</span>] }

provisioner <span class="hljs-string">"powershell"</span> { scripts = [<span class="hljs-string">"Scripts/CloudWatchAgent.ps1"</span>] }

<span class="hljs-comment"># style of the s

Options

cript</span>

$ <span class="hljs-built_in">cat</span> flexeraInstall.ps1

Write-Host <span class="hljs-string">'Stage: Install Flexera Agent ...'</span>

Expand-Archive -LiteralPath C:\temp\TfNSW-Flex-Windows-Agents.zip -DestinationPath c:\temp & <span class="hljs-string">"C:\temp\Windows Agents\Server Agent\setup.exe"</span> /S /v/qn

Write-Host <span class="hljs-string">'Stage: Install Flexera Agent, is done ...'</span></pre></div><h1 id="08aa">Other improvements</h1><h2 id="566e">Share images via AWS Orgazinations</h2><p id="6d47">AWS has new feature ready to <a href="https://aws.amazon.com/about-aws/whats-new/2021/10/amazon-ec2-amazon-machine-images-organizations/">share AMI image to Orgaziations directly</a>, so we don’t need to clollect AWS account IDs and add permission to them one by one, if your AWS enviroinment has been AWS Org ready.</p><p id="4a15">Second, it will be convenience to manage alive accounts, when new accounts to be added or old accounts to be suspended, these accounts’ permission on golden images will be managed at Org layer automatically</p><p id="fd23">Python code for reference</p><div id="eec2"><pre><span class="hljs-keyword">import</span> boto3

imageId=<span class="hljs-string">"<ami id>"</span> organizationArn=<span class="hljs-string">"<org root arn>"</span>

ec2=boto3.client(<span class="hljs-string">'ec2'</span>)

ec2.modify_image_attribute( ImageId = imageId, LaunchPermission = { <span class="hljs-string">'Add'</span> : [{ <span class="hljs-string">'OrganizationArn'</span>: organizationArn}] } )</pre></div><h2 id="329f">Share images in Azure via Computer Gallery</h2><p id="ae8f">In Azure, it is not easy task, you can’t share the images directly to other subscriptions, you need manage them via <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/azure-compute-gallery">Azure computer Gallery</a>.</p><p id="8861"><a href="https://learn.microsoft.com/en-us/azure/virtual-machines/shared-image-galleries?tabs=azure-cli">Follow azure official document </a>, general tasks are</p><ul><li>create computer gallery. Make sure all clients who want to use the images, has read permission to access the computer gallery.</li><li>create VM image definiations, you need create the definiations for each OS, such as RHEL8, RHEL9, Ubuntu20.04, Ubuntu22.04, Windows2019, Windows2022, etc.</li><li><a href="https://learn.microsoft.com/en-us/azure/virtual-machines/image-version?tabs=portal%2Ccli2">Share images you built with pipelines, save it as image versions</a></li><li>Azure Computer Gallery will mark the latest image you shared as latest version, so it would be convenience for you in your IaC (infrastrucure as code).</li></ul><h2 id="c1ef">Mark the image to be Ops Team owned</h2><p id="91b9">In last image build stage, we touch a file with below format into images</p><ul><li><b>Windows</b>: C:\Windows\OpsTeam.json</li><li><b>Linux</b>: /etc/OpsTeam.json</li></ul><div id="e21b"><pre><span class="hljs-punctuation">{</span> <span class="hljs-attr">"ImageCreatedBy"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"OpsTeamXXX"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"ImageCreatedDate"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"2023-05-06"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"soureImageId"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ami-0dd7b8072b9ecxxxx"</span> <span class="hljs-punctuation">}</span></pre></div><p id="6660">With this way, we know the image is built by my Ops team.</p><h1 id="2766">Learning is fun</h1><p id="9446">#DevOps #AWS #Azure #BestPractices #Clouds #Packer #Hashicorp #Solutions</p></article></body>

[Packer] The new design to build golden images for multiple cloud platforms

Follow up on my Virtual machine blogs about

Faced with the challenge of managing two cloud platforms (AWS and Azure) for the Golden Image service, there is a need for a new design aimed at minimizing maintenance time.

The document would be generic to cover other cloud platforms and on-prem as well.

Problem statements

  • Currently my Ops team need prepare the Golden Images monthly (automation builds) for both AWS and Azure Cloud platforms
  • Within AWS, my team uses the AWS managed service EC2 Image Builder for creating golden images has proven challenging. The service is unfriendly and less effective design, particularly when troubleshooting issues. Debugging is difficult due to a lack of comprehensive logs. Currently, I am still unable to reserve the building EC2 instances, I can’t login and perform manual checks to identify issues.
  • Within Azure, there’s a managed service known as VM Image Builder, built on HashiCorp Packer. However, the Azure documentation is unclear, prompting us to opt for direct implementation using HashiCorp Packer.
  • In many cases, updating something requires duplicating the same changes to another cloud platform. Due to differences in the two image build environments, extra time to adjust codes are necessary as well.
  • CIS hardening poses an additional challenge as we must maintain two sets of hardening codes for different cloud platforms, even though the codes are essentially the same.

Research insights

We have built Azure golden images with HashiCorp Packer, I’d like to use the same tool to build golden images in AWS as well.

  • We can achieve consistent solutions by using Packer templates for both Azure and AWS
  • Both sets of build codes can be merged into one and managed in the same Git repository.
  • We get benifits from exist Azure Packer template, most codes can be re-used for AWS packer templates
  • We can use the centralized source codes for CIS hardening as well.
  • Furthermore, the installation scripts can be shared between Azure and AWS, requiring only one-time writing and updating for both platforms
  • As a bonus, convert exist Packer json template to HCL2 offers advantages such as avoiding the need for verbose JSON syntax, allowing for comments, and providing flexibility in adjusting codes. For instance, disabling specific provisioners becomes easier by commenting them out, saving both build and test time.

Solution diagram

Here is the updated diagram, with the shared component centralized in the middle, serving both AWS and Azure.

https://excalidraw.com/#json=wcnAiyTnkWsk-WHoL6IlD,tSxa74dCQMQPKV5uBvbmsA

You can refer this link to view above diagram on excalidraw

Git code’s folders for reference

Git repo root for codes of image builder
|- CIS        # put all CIS hardening scripts, share between AWS and Azure
  |- AL2023
  |- RHEL8
  |- RHEL9
  |- Win2019
  |- Win2022
|-Scripts    # put all install scripts, share between AWS and Azure
  |-Linux
    |- CloudWatchAgent.sh
    |- SplunkAgent.sh
    |- CrowdStrike.sh
    |- CIS-hardening.sh
    |- AzureVMAgent.sh
  |-Windows
    |- CloudWatchAgent.ps1
    |- SplunkAgent.ps1
    |- CrowdStrike.ps1
    |- CIS-hardening.ps1
    |- AzureVMAgent.ps1
|- Pipelines  # Azure DevOps Pipeline supports multiple pipeline files
  |- aws-pipeline.yaml
  |- azure-pipeline.yaml
|- PackerTemplates  # Prepare packer template for each linux and Windows system
  |- rhel8-aws.pkr.hcl
  |- rhel9-aws.pkr.hcl
  |- al2023-aws.pkr.hcl
  |- amaz2-aws.pkr.hcl
  |- win2019-aws.pkr.hcl
  |- rhel8-azure.pkr.hcl
  |- rhel9-azure.pkr.hcl
  |- win2019-azure.pkr.hcl

Four main folders in the source codes

  • CIS — put all CIS hardening scripts, group for different OS systems, share between AWS and Azure
  • Scripts — put all install and configuration scripts, write for both Linux Bash script and Windows PowerShell scripts, share between AWS and Azure
  • Pipelines — two pipelines for both AWS and Azure
  • PackerTemplates — Prepare packer templates for each linux and Windows system on AWS and Azure

Explanation and general rules

  • No agent binary packages should be saved in git repository directly. Copy from AWS s3 bucket or Azure Storage Account. This is for some agent install packages, which can’t be downloaded from public links directly
  • If you have software active codes, license IDs, recommends to save to AWS SSM parameter/secret manager, or Azure Key/Vault.
  • When image building, all configuration files and binary packages, could be copied to same destination, for exmaple, C:\temp (Windows) or /tmp (Linux) , in the build instances
  • All commands should not be directly put in packer templates, always called from shell or powershell script. With this way, same scripts can be shared between AWS and Azure image Builds. Remeber to put a comments in the script, so we know the build stages. For example
# Packer code:
 
provisioner "powershell" {
  scripts = ["Scripts/SplunkAgent.ps1"]
}

provisioner "powershell" {
  scripts = ["Scripts/CloudWatchAgent.ps1"]
}

# style of the script
 
$ cat flexeraInstall.ps1
 
Write-Host 'Stage: Install Flexera Agent ...'
 
Expand-Archive -LiteralPath C:\temp\TfNSW-Flex-Windows-Agents.zip -DestinationPath c:\temp
& "C:\temp\Windows Agents\Server Agent\setup.exe" /S /v/qn

Write-Host 'Stage: Install Flexera Agent, is done ...'

Other improvements

Share images via AWS Orgazinations

AWS has new feature ready to share AMI image to Orgaziations directly, so we don’t need to clollect AWS account IDs and add permission to them one by one, if your AWS enviroinment has been AWS Org ready.

Second, it will be convenience to manage alive accounts, when new accounts to be added or old accounts to be suspended, these accounts’ permission on golden images will be managed at Org layer automatically

Python code for reference

import boto3
 
imageId="<ami id>"
organizationArn="<org root arn>"
 
ec2=boto3.client('ec2')

ec2.modify_image_attribute(
    ImageId = imageId,
    LaunchPermission = {
        'Add' : [{ 'OrganizationArn': organizationArn}]
    }
)

Share images in Azure via Computer Gallery

In Azure, it is not easy task, you can’t share the images directly to other subscriptions, you need manage them via Azure computer Gallery.

Follow azure official document , general tasks are

  • create computer gallery. Make sure all clients who want to use the images, has read permission to access the computer gallery.
  • create VM image definiations, you need create the definiations for each OS, such as RHEL8, RHEL9, Ubuntu20.04, Ubuntu22.04, Windows2019, Windows2022, etc.
  • Share images you built with pipelines, save it as image versions
  • Azure Computer Gallery will mark the latest image you shared as latest version, so it would be convenience for you in your IaC (infrastrucure as code).

Mark the image to be Ops Team owned

In last image build stage, we touch a file with below format into images

  • Windows: C:\Windows\OpsTeam.json
  • Linux: /etc/OpsTeam.json
{
   "ImageCreatedBy": "OpsTeamXXX",
   "ImageCreatedDate": "2023-05-06",
   "soureImageId": "ami-0dd7b8072b9ecxxxx"
}

With this way, we know the image is built by my Ops team.

Learning is fun

#DevOps #AWS #Azure #BestPractices #Clouds #Packer #Hashicorp #Solutions

Bestpickers
DevOps
Hashicorp Packer
Cloud
Solutions
Recommended from ReadMedium