Files
aws.ssm.documents/UpdateWindows2025Ami.yaml
T

249 lines
8.7 KiB
YAML

schemaVersion: '0.3'
description: Cloned from AWS-UpdateWindowsAmi. Removed steps such that this document works with Windows Server 2025.
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
SourceAmiId:
type: String
description: (Required) The source Amazon Machine Image ID.
IamInstanceProfileName:
type: String
description: (Required) The name of the role that enables Systems Manager to manage the instance.
default: ManagedInstanceProfile
AutomationAssumeRole:
type: String
description: (Required) The ARN of the role that allows Automation to perform the actions on your behalf.
default: arn:aws:iam::{{global:ACCOUNT_ID}}:role/AutomationServiceRole
TargetAmiName:
type: String
description: (Optional) The name of the new AMI that will be created. Default is a system-generated string including the source AMI id, and the creation time and date.
default: UpdateWindowsAmi_from_{{SourceAmiId}}_on_{{global:DATE_TIME}}
TargetImageDescription:
type: String
description: (Optional) The description of the new AMI that will be created.
default: Updated Windows Ami from {{SourceAmiId}} on {{global:DATE_TIME}}
InstanceType:
type: String
description: (Optional) Type of instance to launch as the workspace host. Instance types vary by region. Default is t3.medium.
default: t3.medium
SecurityGroupIds:
type: StringList
description: (Optional) A comma separated list of security group IDs with the required Inbound and Outbound connectivity rules.
allowedPattern: ^sg-[a-z0-9]{8,17}$
default: []
SubnetId:
type: String
description: (Optional) Specify the SubnetId if you want to launch into a specific subnet.
default: ''
PreUpdateScript:
type: String
description: (Optional) A script provided as a string. It will execute prior to installing OS updates.
default: ''
PostUpdateScript:
type: String
description: (Optional) A script provided as a string. It will execute after installing OS updates.
default: ''
MetadataOptions:
type: StringMap
description: (Optional) The metadata options for the instance.
default:
HttpEndpoint: enabled
HttpTokens: optional
mainSteps:
- name: LaunchInstance
action: aws:runInstances
maxAttempts: 3
timeoutSeconds: 1800
nextStep: RunPreUpdateScript
isEnd: false
onFailure: Abort
inputs:
ImageId: '{{ SourceAmiId }}'
InstanceType: '{{ InstanceType }}'
MinInstanceCount: 1
MaxInstanceCount: 1
IamInstanceProfileName: '{{ IamInstanceProfileName }}'
SubnetId: '{{ SubnetId }}'
SecurityGroupIds: '{{SecurityGroupIds}}'
MetadataOptions: '{{MetadataOptions}}'
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: SSM-TempInstanceForPatching-{{global:DATE_TIME}}
- Key: SSMDocumentName
Value: HJ-UpdateWindows2025Ami
- name: RunPreUpdateScript
action: aws:runCommand
maxAttempts: 3
timeoutSeconds: 1800
nextStep: UpdateEC2Config
isEnd: false
onFailure: Abort
inputs:
DocumentName: AWS-RunPowerShellScript
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
Parameters:
commands: '{{ PreUpdateScript }}'
- name: UpdateEC2Config
action: aws:runCommand
maxAttempts: 3
timeoutSeconds: 7200
nextStep: InstallUpdatesAndReboot
isEnd: false
onFailure: Abort
inputs:
DocumentName: AWS-RunPowerShellScript
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
Parameters:
commands:
- $zipFilename = 'AWSUpdateWindowsInstance.zip'
- $zipFileHash = '0BD8C683CEFD69D975D2F3AE3B9EAFB533F6037D58427B65DB36934D7B6B70FD'
- $moduleName = 'AWSUpdateWindowsInstance'
- $tempPath = $env:TEMP
- $moduleDirectory = Join-Path $tempPath -ChildPath $moduleName
- $nonOptInRegions = @('ap-northeast-1', 'ap-northeast-2', 'ap-northeast-3', 'ap-south-1', 'ap-southeast-1', 'ap-southeast-2', 'ca-central-1', 'eu-central-1', 'eu-north-1', 'eu-west-1', 'eu-west-2', 'eu-west-3', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2')
- $moduleZipFilePath = Join-Path $tempPath -ChildPath $zipFilename
- $moduleManifestPath = Join-Path $moduleDirectory -ChildPath ('{0}.psd1' -f $moduleName)
- ''
- $ssmAgentService = Get-ItemProperty 'HKLM:SYSTEM\CurrentControlSet\Services\AmazonSSMAgent\' -ErrorAction SilentlyContinue
- $region = $env:AWS_SSM_REGION_NAME
- ''
- function Main {
- ' $ec2launchV2 = "$($env:ProgramFiles)\Amazon\EC2Launch\EC2Launch.exe"'
- ''
- ' if (Test-Path $ec2launchV2) {'
- ' return'
- ' }'
- ''
- ' if ([Environment]::OSVersion.Version.Major -ge 10) {'
- ' Invoke-UpdateEC2Launch'
- ' } else {'
- ' Invoke-UpdateEC2Config'
- ' }'
- '}'
- ''
- function Invoke-UpdateEC2Config {
- ' try {'
- ' Import-Module $moduleManifestPath'
- ' $command = "Install-AwsUwiEC2Config -Region $region"'
- ' if($id) { $command += " -Id $($id)"}'
- ' Invoke-Expression $command'
- ' } catch {'
- ' Write-Host ''Executing Invoke-AwsUwiEC2Config resulted in error: $($_)'''
- ' Exit -1'
- ' }'
- '}'
- ''
- function Invoke-UpdateEC2Launch {
- ' try {'
- ' Import-Module $moduleManifestPath'
- ' $command = ''Install-AwsUwiEC2Launch'''
- ' if($id) { $command += " -Id $($id)" }'
- ' Invoke-Expression $command'
- ' } catch {'
- ' Write-Host ''Executing Invoke-AwsUwiEC2Launch resulted in error: $($_)'''
- ' Exit -1'
- ' }'
- '}'
- ''
- Main
- name: InstallUpdatesAndReboot
action: aws:runCommand
nextStep: WaitForInstanceOnline
isEnd: false
onFailure: step:TerminateInstance
inputs:
DocumentName: AWS-RunPowerShellScript
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
Parameters:
commands:
- |
net stop bits
net stop wuauserv
Remove-Item -Recurse -Force "$env:SystemRoot\SoftwareDistribution\*" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "$env:SystemRoot\System32\catroot2\*" -ErrorAction SilentlyContinue
net start bits
net start wuauserv
Install-Module PSWindowsUpdate -Force -Scope AllUsers
Import-Module PSWindowsUpdate
Install-WindowsUpdate -AcceptAll -Confirm:$false -AutoReboot
- name: WaitForInstanceOnline
action: aws:waitForAwsResourceProperty
timeoutSeconds: 600
nextStep: RunPostUpdateScript
isEnd: false
inputs:
Service: ssm
Api: DescribeInstanceInformation
InstanceInformationFilterList:
- key: InstanceIds
valueSet:
- '{{ LaunchInstance.InstanceIds }}'
PropertySelector: $.InstanceInformationList[0].PingStatus
DesiredValues:
- Online
- name: RunPostUpdateScript
action: aws:runCommand
maxAttempts: 3
timeoutSeconds: 1800
nextStep: RunSysprepGeneralize
isEnd: false
onFailure: Abort
inputs:
DocumentName: AWS-RunPowerShellScript
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
Parameters:
commands: '{{ PostUpdateScript }}'
- name: RunSysprepGeneralize
action: aws:runCommand
maxAttempts: 3
timeoutSeconds: 600
nextStep: StopInstance
isEnd: false
onFailure: Abort
inputs:
DocumentName: AWSEC2-RunSysprep
InstanceIds:
- '{{LaunchInstance.InstanceIds}}'
Parameters:
Id: '{{automation:EXECUTION_ID}}'
- name: StopInstance
action: aws:changeInstanceState
maxAttempts: 3
timeoutSeconds: 7200
nextStep: CreateImage
isEnd: false
onFailure: Abort
inputs:
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
CheckStateOnly: false
DesiredState: stopped
- name: CreateImage
action: aws:createImage
maxAttempts: 3
nextStep: TerminateInstance
isEnd: false
onFailure: Abort
inputs:
InstanceId: '{{ LaunchInstance.InstanceIds }}'
ImageName: '{{ TargetAmiName }}'
NoReboot: true
ImageDescription: '{{ TargetImageDescription }}'
- name: TerminateInstance
action: aws:changeInstanceState
maxAttempts: 3
isEnd: true
onFailure: Abort
inputs:
InstanceIds:
- '{{ LaunchInstance.InstanceIds }}'
DesiredState: terminated
outputs:
- CreateImage.ImageId