Set up a Maintenance Window to schedule SSM Patch Manager
The following pages discuss the patch baseline.
In this case, we will consider setting up a schedule for applying patches.
Scheduling patches can be done by setting up a maintenance window.
After you configure a patch baseline (and optionally a patch group), you can apply patches to your node by using a maintenance window.
About patching schedules using maintenance windows
This time, we will use CloudFormation to set up the maintenance window, referring to the following official AWS page.
Environemnt
Place one EC2 instance in a private subnet.
The instance will be Amazon Linux 2.
Set up a maintenance window.
The content is to periodically run the SSM document AWS-RunPatchBaseline.
Running this document will cause the instance to run AWS-AmazonLinux2DefaultPatchBaseline, which is the default for Amazon Linux 2.
Save Patch Manager execution logs to S3 bucket.
CloudFormation template files
The above configuration is built with CloudFormation.
The CloudFormation templates are placed at the following URL
https://github.com/awstut-an-r/awstut-fa/tree/main/116
Explanation of key points of template files
When setting up a maintenance window, set up the following three resources
- Maintenance Window
- Maintenance Window Target
- Maintenance Window Task
Maintenance Window
Resources:
MaintenanceWindow:
Type: AWS::SSM::MaintenanceWindow
Properties:
AllowUnassociatedTargets: true
Cutoff: 1
Description: My-First-Maintenance-Window
Duration: 2
Name: !Sub "${Prefix}-MaintenanceWindow"
Schedule: rate(5 minutes)
ScheduleTimezone: Asia/Tokyo
Code language: YAML (yaml)
The following page covers how to create a maintenance window using the AWS CLI.
https://docs.aws.amazon.com/systems-manager/latest/userguide/mw-cli-tutorial-create-mw.html
Create CloudFormation templates based on the above.
The settings are as follows
Runs every five minutes for up to two hours (as needed).
Step 1: Create the maintenance window (AWS CLI)
Prevents new tasks from starting within one hour of the end of the maintenance window operation.
Allows unassociated targets (instances that you haven’t registered with the maintenance window).
Maintenance Window Target
Resources:
MaintenanceWindowTarget:
Type: AWS::SSM::MaintenanceWindowTarget
Properties:
Description: My-First-Maintenance-Window-Target
Name: !Sub "${Prefix}-MaintenanceWindowTarget"
ResourceType: INSTANCE
Targets:
- Key: tag:Patch Group
Values:
- !Ref PatchGroupTag
WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)
The following page covers how to create a maintenance window target using the AWS CLI.
https://docs.aws.amazon.com/systems-manager/latest/userguide/mw-cli-tutorial-targets.html
Create CloudFormation templates based on the above.
Instances tagged with the following conditions are considered as maintenance window targets.
- Key: Patch Group
- Value: my-patch-group
To specify a tag name for the Key property, use the “tag:[tag name]” format.
Maintenance Window Task
Resources:
MaintenanceWindowTask:
Type: AWS::SSM::MaintenanceWindowTask
Properties:
Description: My-First-Maintenance-Window
MaxConcurrency: 1
MaxErrors: 1
Name: !Sub "${Prefix}-MaintenanceWindowTask"
Priority: 10
Targets:
- Key: WindowTargetIds
Values:
- !Ref MaintenanceWindowTarget
TaskArn: AWS-RunPatchBaseline
TaskInvocationParameters:
MaintenanceWindowRunCommandParameters:
OutputS3BucketName: !Ref S3BucketName
Parameters:
Operation:
- Install
TaskType: RUN_COMMAND
WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)
The following page covers how to create maintenance window tasks using the AWS CLI.
https://docs.aws.amazon.com/systems-manager/latest/userguide/mw-cli-tutorial-tasks.html
Create CloudFormation templates based on the above.
The task to be created is to run AWS-RunPatchBaseline.
The TaskInvocationParameters property allows you to set parameters for running AWS-RunPatchBaseline.
Please refer to the following page for more information on parameters.
This time, only the mandatory parameter, Operation, is set.
Specify “Install” to perform not only scanning but also installation.
(Reference) EC2 instance
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref InstanceSecurityGroup
Tags:
- Key: Patch Group
Value: !Ref PatchGroupTag
Code language: YAML (yaml)
The key point is the tag settings.
The settings are similar to those specified in the maintenance window target.
Architecting
Use CloudFormation to build this environment and check its actual behavior.
Create a CloudFormation stacks and check the resources in the stacks
Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following pages.
After reviewing the resources in each stack, information on the main resources created in this case is as follows
- EC2 Instance: i-0ff14606b3c6f9e57
- Maintenance Window: mw-005d1fe0cee81a8f0
Check each resource from the AWS Management Console.
Check the maintenance window.
You can see that the task is set to run every 5 minutes.
Looking at the content of the task, we can see that the content is to run AWS-RunPatchBaseline.
Instances with the tag key “Patch Group” and the value “my-patch-group” are the target of the maintenance window.
Operation Check
Now that it is ready, check its operation.
After waiting for a while, the history shows that the task has been executed.
Indeed, the task was executed for the instance.
You can check what has been executed.
In this case, we have set up the S3 bucket to store the execution log, so we will check there.
The following is a partial list of file contents.
/usr/bin/python3
/usr/bin/python2.7
/usr/bin/python2
/usr/bin/python
/usr/bin/yum
Using Yum version: 3.4.3
Using python binary: 'python2.7'
Using Python Version: Python 2.7.18
01/15/2023 11:59:24 root [INFO]: Downloading payload from https://s3.dualstack.ap-northeast-1.amazonaws.com/aws-ssm-ap-northeast-1/patchbaselineoperations/linux/payloads/patch-baseline-operations-1.101.tar.gz
01/15/2023 11:59:25 root [INFO]: Attempting to import entrance file os_selector
01/15/2023 11:59:25 root [INFO]: Running with snapshot id = 65deccb0-8b50-4d9e-9021-806637490599 and operation = Install
01/15/2023 11:59:25 root [INFO]: Instance Id: i-0ff14606b3c6f9e57
01/15/2023 11:59:25 root [INFO]: Region: ap-northeast-1
01/15/2023 11:59:25 root [INFO]: Product: AmazonLinux2
01/15/2023 11:59:25 root [INFO]: Patch Group: my-patch-group
01/15/2023 11:59:25 root [INFO]: Operation type: Install
01/15/2023 11:59:25 root [INFO]: Snapshot Id: 65deccb0-8b50-4d9e-9021-806637490599
01/15/2023 11:59:25 root [INFO]: Patch Baseline: {u'approvedPatchesEnableNonSecurity': False, u'baselineId': u'pb-00fda5699d1ae3942', u'name': u'AWS-AmazonLinux2DefaultPatchBaseline', u'modifiedTime': 1529573088.054, u'description': u'Default Patch Baseline for Amazon Linux 2 Provided by AWS.', u'rejectedPatches': [], u'globalFilters': {u'filters': [{u'values': [u'*'], u'key': u'PRODUCT'}]}, u'sources': [], u'approvalRules': {u'rules': [{u'enableNonSecurity': False, u'filterGroup': {u'filters': [{u'values': [u'Security'], u'key': u'CLASSIFICATION'}, {u'values': [u'Critical', u'Important'], u'key': u'SEVERITY'}]}, u'approveAfterDays': 7, u'complianceLevel': u'UNSPECIFIED', u'approveUntilDate': None}, {u'enableNonSecurity': False, u'filterGroup': {u'filters': [{u'values': [u'Bugfix'], u'key': u'CLASSIFICATION'}]}, u'approveAfterDays': 7, u'complianceLevel': u'UNSPECIFIED', u'approveUntilDate': None}]}, u'createdTime': 1529573088.054, u'rejectedPatchesAction': u'ALLOW_AS_DEPENDENCY', u'approvedPatchesComplianceLevel': u'UNSPECIFIED', u'operatingSystem': u'AMAZON_LINUX_2', u'approvedPatches': [], u'accountId': u'486716784251'}
...
01/15/2023 12:00:06 root [INFO]: Instance is Compliant
...
01/15/2023 12:00:06 root [INFO]: Attempting full upload
01/15/2023 12:00:06 root [INFO]: Upload complete.
01/15/2023 12:00:06 root [INFO]: Report upload successful.
01/15/2023 12:00:06 root [INFO]: Inventory upload was successful.
01/15/2023 12:00:06 root [INFO]: Reboot is not required
01/15/2023 12:00:06 root [INFO]: Inventory upload was successful.
01/15/2023 12:00:06 root [INFO]: Reboot is not required
Code language: plaintext (plaintext)
Indeed, AWS-RunPatchBaseline was executed to update the various modules in the instance.
Finally, check the execution history of the task again.
You can check the history of the second task execution.
It can be seen that the second task was executed 5 minutes after the first execution.
This shows that the task was indeed executed according to the schedule specified in the rate expression.
Summary
We have identified a way to set up a maintenance window and schedule patches.