orion
anderson

Grimoire Entries tagged with “PowerShell”

Check AMI with PowerShell

A Simple Lambda function to check your launch template AMI against the latest Bottlerocket AMI (or any AMI) and publish an SNS message if a new AMI exists.

Create a LaunchTemplateId environment variable in Lambda console to the ID of your launch template. Create an AmiId environment variable with the value of the AMI ID you want to check against, for example, /aws/service/bottlerocket/aws-ecs-1/x86_64/latest/image_id.

☝ Tip 1: Run this Lambda on a schedule or trigger it from a GitHub webhook.

☝ Tip 2: Send the output to SNS Topic that triggers another lambda function that updates your launch templates automatically or triggers auto-scaling group instance refreshes.

Requires -Modules @{ModuleName='AWS.Tools.Common';ModuleVersion='4.1.0.0';}
Requires -Modules @{ModuleName='AWS.Tools.SimpleSystemsManagement';ModuleVersion='4.1.0.0';}
Requires -Modules @{ModuleName='AWS.Tools.EC2';ModuleVersion='4.1.0.0';}
Requires -Modules @{ModuleName='AWS.Tools.SimpleNotificationService';ModuleVersion='4.1.0.0';}

# Uncomment to send the input event to CloudWatch Logs
# Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5)

$LaunchTemplateId = $Env:LaunchTemplateID
$LatestAMI = (Get-SSMParameter $Env:AmiId).Value

$UsingAMI = (
    Get-EC2TemplateVersion `
        -LaunchTemplateId $LaunchTemplateId `
        -Version "`$Latest"
).LaunchTemplateData.ImageId

If ($UsingAMI -ne $LatestAMI) {

    Publish-SNSMessage `
        -TopicArn "arn:aws:sns:us-east-2:XXXXXXXXXXXX:SNS_TOPIC" `
        -Message "The latest AMI is: $LatestAMI" `
        -Subject "🚀New Bottlerocket AMI!🚀"

    $Message = "New ami: $LatestAMI"
}
Else {
    $Message = "No new AMI."
}

Return $Message

Parameter Input vs Pipeline Input

Parameter input sends the input parameter object to the function.

Pipeline input reads from the pipeline, one object at a time. Pipeline input requires an advanced function with Begin, Process, End blocks.

Example that finds duplicates in an array:

$MyArray = @(1, 2, 3, 4, 5, 1, 1, 6, 6, 32, "adam", "adam")

Function Find-DuplicatesFromParameters {
  Param(
    [Parameter(Mandatory = $true)]
    [array]$InputArray
  )

  $DuplicateItems = $InputArray |
  Group-Object | Where-Object { $_.Count -gt 1 }

  $DuplicateItems | ForEach-Object {
    $Count = $_ | Select-Object -ExpandProperty Count
    Write-Output "$($_.Name) `t ($Count times)"
  }
}

Function Find-DuplicatesFromPipeline {
  [CmdletBinding()]
  Param(
    [Parameter(ValueFromPipeline)]
    [array]$InputArray
  )

  Begin {
    $TempArray = @()
  }
  Process {
    $TempArray += $_
  }

  End {
    $TempArray |
    Group-Object | Where-Object { $_.Count -gt 1 } |
    ForEach-Object {
      $Count = $_ | Select-Object -ExpandProperty Count
      Write-Output "$($_.Name) `t ($Count times)"
    }
  }
}

Find-DuplicatesFromParameters -InputArray $MyArray

$MyArray | Find-DuplicatesFromPipeline