Final Post — Concept: Alexa Golden Images with Packer on AWS, Azure, and GCP

Note: Alexa could understand the word Azure and acronym AWS, but struggled with ‘GCP’ half the time, so I opted into using the Company names; Amazon, Microsoft, and Google for user utterances.

Note: The point of this part was that if you wanted to build an Azure image, you could also get an inspector scan. This would build the same image on AWS which could be validated with an inspector scan since Azure and GCP don’t offer a similar service.

{
"variables": {
"aws_access_key": "",
"aws_secret_key": "",
"packer_vpc_id": "",
"packer_subnet_id": "",
"packer_security_group": "",
"ami_name": ""
},
"builders": [{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"type": "amazon-ebs",
"region": "us-east-1",
"source_ami": "ami-0947d2ba12ee1ff75",
"instance_type": "m4.large",
"ssh_username": "ec2-user",
"ami_name": "{{user `ami_name`}}",
"ssh_timeout": "5m",
"iam_instance_profile": "SSMAutomationPackerCF",
"vpc_id": "{{user `packer_vpc_id`}}",
"subnet_id": "{{user `packer_subnet_id`}}",
"security_group_id": "{{user `packer_security_group`}}",
"associate_public_ip_address": true
}],
"provisioners": [{
"type": "shell",
"inline": ["sudo yum update -y"]
}]
}
{
"variables": {
"client_id": "",
"client_secret": "",
"tenant_id": "",
"subscription_id": "",
"location": "",
"managed_image_name": ""
},
"builders": [{
"type": "azure-arm",
"client_id": "{{ user `client_id` }}",
"client_secret": "{{ user `client_secret` }}",
"tenant_id": "{{ user `tenant_id` }}",
"subscription_id": "{{ user `subscription_id` }}",
"managed_image_resource_group_name": "packer-azure-resource-group",
"managed_image_name": "{{ user `managed_image_name` }}",
"os_type": "Linux",
"image_publisher": "Canonical",
"image_offer": "UbuntuServer",
"image_sku": "18.04-LTS",
"image_version": "latest",
"location": "{{ user `location` }}",
"vm_size": "Standard_B2s"
}],
"provisioners": [{
"type": "shell",
"inline": ["sudo yum update -y"]
}]
}
{
"variables": {
"account_file": "",
"project_id": "",
"zone": "",
"image_name": ""
},
"builders": [{
"type": "googlecompute",
"project_id": "{{user `project_id`}}",
"source_image": "debian-9-stretch-v20200805",
"zone": "{{user `zone`}}",
"ssh_username": "packer",
"account_file": "{{ user `service_account_json`}}",
"image_name": "{{ user `image_name`}}"
}],
"provisioners": [{
"type": "shell",
"inline": ["sudo yum update -y"]
}]
}

NOTE: Important to call out here that several values in the build files are updated by in the Request Parser lambda’s environment variables set by the Terraform.

ssm_client = boto3.client('ssm', region_name=region)
response = ssm_client.start_automation_execution(
DocumentName='AWS-RunPacker',
Parameters={
"TemplateFileName": <template_file>,
"TemplateS3BucketName": <bucket_name>,
"Mode": ["Build"]
}
)
execution_id = response["AutomationExecutionId"]
status = "InProgress"
while status in ["Pending","InProgress"]:
updated = ssm_client.get_automation_execution(AutomationExecutionId=execution_id)
status = updated['AutomationExecution']['AutomationExecutionStatus']
print(status)
time.sleep(15)
findings_response = inspector_client.list_findings(
assessmentRunArns=[event['AWS']],
filter={
'severities': ['High']
}
)
findings_details = inspector_client.describe_findings(findingArns=findings_list, locale='EN_US')
def parse_findings(findings_data):
""" Parse findings into something useful """
findings_parsed =[]
for details in findings_data['findings']:
if details is not None:
details['recommendation'] = re.sub('\s+',' ', details['recommendation']).strip()
details['title'] = re.sub('\s+',' ', details['title']).strip()
details['description'] = re.sub('\s+',' ', details['description']).strip().replace('Description ', 'Description: ')
finding = {
"rule_id": details['id'].strip(),
"recommendation": details['recommendation'],
"severity": details['severity'].strip(),
"title": details['title'],
"description": details['description']
}
findings_parsed.append(finding)
return findings_parsed

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store