Configure AWS Systems Manager Patch Baselines

The aws:ssm/patchBaseline:PatchBaseline resource, part of the Pulumi AWS provider, defines patch approval policies for SSM Patch Manager: which patches to install, when to approve them, and where to source them. This guide focuses on three capabilities: explicit patch approval by KB number, rule-based automatic approval with filters, and custom patch repositories.

Patch baselines define policies but don’t apply them directly. You must associate baselines with patch groups and maintenance windows to actually patch instances. The examples are intentionally small. Combine them with your own patch groups, maintenance windows, and managed instances.

Approve specific patches by KB number

Teams managing Windows servers often start with a minimal baseline that explicitly approves known patches by their KB identifiers.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const production = new aws.ssm.PatchBaseline("production", {
    name: "patch-baseline",
    approvedPatches: ["KB123456"],
});
import pulumi
import pulumi_aws as aws

production = aws.ssm.PatchBaseline("production",
    name="patch-baseline",
    approved_patches=["KB123456"])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ssm"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ssm.NewPatchBaseline(ctx, "production", &ssm.PatchBaselineArgs{
			Name: pulumi.String("patch-baseline"),
			ApprovedPatches: pulumi.StringArray{
				pulumi.String("KB123456"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var production = new Aws.Ssm.PatchBaseline("production", new()
    {
        Name = "patch-baseline",
        ApprovedPatches = new[]
        {
            "KB123456",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ssm.PatchBaseline;
import com.pulumi.aws.ssm.PatchBaselineArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var production = new PatchBaseline("production", PatchBaselineArgs.builder()
            .name("patch-baseline")
            .approvedPatches("KB123456")
            .build());

    }
}
resources:
  production:
    type: aws:ssm:PatchBaseline
    properties:
      name: patch-baseline
      approvedPatches:
        - KB123456

The approvedPatches property lists specific KB numbers that Patch Manager will install on managed nodes. This approach gives you direct control over which updates reach your servers without automatic approval rules.

Combine explicit approvals with automatic approval rules

Production environments often need both explicit patch control and automatic approval for patches matching specific criteria.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const production = new aws.ssm.PatchBaseline("production", {
    name: "patch-baseline",
    description: "Patch Baseline Description",
    approvedPatches: [
        "KB123456",
        "KB456789",
    ],
    rejectedPatches: ["KB987654"],
    globalFilters: [
        {
            key: "PRODUCT",
            values: ["WindowsServer2008"],
        },
        {
            key: "CLASSIFICATION",
            values: ["ServicePacks"],
        },
        {
            key: "MSRC_SEVERITY",
            values: ["Low"],
        },
    ],
    approvalRules: [
        {
            approveAfterDays: 7,
            complianceLevel: "HIGH",
            patchFilters: [
                {
                    key: "PRODUCT",
                    values: ["WindowsServer2016"],
                },
                {
                    key: "CLASSIFICATION",
                    values: [
                        "CriticalUpdates",
                        "SecurityUpdates",
                        "Updates",
                    ],
                },
                {
                    key: "MSRC_SEVERITY",
                    values: [
                        "Critical",
                        "Important",
                        "Moderate",
                    ],
                },
            ],
        },
        {
            approveAfterDays: 7,
            patchFilters: [{
                key: "PRODUCT",
                values: ["WindowsServer2012"],
            }],
        },
    ],
});
import pulumi
import pulumi_aws as aws

production = aws.ssm.PatchBaseline("production",
    name="patch-baseline",
    description="Patch Baseline Description",
    approved_patches=[
        "KB123456",
        "KB456789",
    ],
    rejected_patches=["KB987654"],
    global_filters=[
        {
            "key": "PRODUCT",
            "values": ["WindowsServer2008"],
        },
        {
            "key": "CLASSIFICATION",
            "values": ["ServicePacks"],
        },
        {
            "key": "MSRC_SEVERITY",
            "values": ["Low"],
        },
    ],
    approval_rules=[
        {
            "approve_after_days": 7,
            "compliance_level": "HIGH",
            "patch_filters": [
                {
                    "key": "PRODUCT",
                    "values": ["WindowsServer2016"],
                },
                {
                    "key": "CLASSIFICATION",
                    "values": [
                        "CriticalUpdates",
                        "SecurityUpdates",
                        "Updates",
                    ],
                },
                {
                    "key": "MSRC_SEVERITY",
                    "values": [
                        "Critical",
                        "Important",
                        "Moderate",
                    ],
                },
            ],
        },
        {
            "approve_after_days": 7,
            "patch_filters": [{
                "key": "PRODUCT",
                "values": ["WindowsServer2012"],
            }],
        },
    ])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ssm"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ssm.NewPatchBaseline(ctx, "production", &ssm.PatchBaselineArgs{
			Name:        pulumi.String("patch-baseline"),
			Description: pulumi.String("Patch Baseline Description"),
			ApprovedPatches: pulumi.StringArray{
				pulumi.String("KB123456"),
				pulumi.String("KB456789"),
			},
			RejectedPatches: pulumi.StringArray{
				pulumi.String("KB987654"),
			},
			GlobalFilters: ssm.PatchBaselineGlobalFilterArray{
				&ssm.PatchBaselineGlobalFilterArgs{
					Key: pulumi.String("PRODUCT"),
					Values: pulumi.StringArray{
						pulumi.String("WindowsServer2008"),
					},
				},
				&ssm.PatchBaselineGlobalFilterArgs{
					Key: pulumi.String("CLASSIFICATION"),
					Values: pulumi.StringArray{
						pulumi.String("ServicePacks"),
					},
				},
				&ssm.PatchBaselineGlobalFilterArgs{
					Key: pulumi.String("MSRC_SEVERITY"),
					Values: pulumi.StringArray{
						pulumi.String("Low"),
					},
				},
			},
			ApprovalRules: ssm.PatchBaselineApprovalRuleArray{
				&ssm.PatchBaselineApprovalRuleArgs{
					ApproveAfterDays: pulumi.Int(7),
					ComplianceLevel:  pulumi.String("HIGH"),
					PatchFilters: ssm.PatchBaselineApprovalRulePatchFilterArray{
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("PRODUCT"),
							Values: pulumi.StringArray{
								pulumi.String("WindowsServer2016"),
							},
						},
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("CLASSIFICATION"),
							Values: pulumi.StringArray{
								pulumi.String("CriticalUpdates"),
								pulumi.String("SecurityUpdates"),
								pulumi.String("Updates"),
							},
						},
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("MSRC_SEVERITY"),
							Values: pulumi.StringArray{
								pulumi.String("Critical"),
								pulumi.String("Important"),
								pulumi.String("Moderate"),
							},
						},
					},
				},
				&ssm.PatchBaselineApprovalRuleArgs{
					ApproveAfterDays: pulumi.Int(7),
					PatchFilters: ssm.PatchBaselineApprovalRulePatchFilterArray{
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("PRODUCT"),
							Values: pulumi.StringArray{
								pulumi.String("WindowsServer2012"),
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var production = new Aws.Ssm.PatchBaseline("production", new()
    {
        Name = "patch-baseline",
        Description = "Patch Baseline Description",
        ApprovedPatches = new[]
        {
            "KB123456",
            "KB456789",
        },
        RejectedPatches = new[]
        {
            "KB987654",
        },
        GlobalFilters = new[]
        {
            new Aws.Ssm.Inputs.PatchBaselineGlobalFilterArgs
            {
                Key = "PRODUCT",
                Values = new[]
                {
                    "WindowsServer2008",
                },
            },
            new Aws.Ssm.Inputs.PatchBaselineGlobalFilterArgs
            {
                Key = "CLASSIFICATION",
                Values = new[]
                {
                    "ServicePacks",
                },
            },
            new Aws.Ssm.Inputs.PatchBaselineGlobalFilterArgs
            {
                Key = "MSRC_SEVERITY",
                Values = new[]
                {
                    "Low",
                },
            },
        },
        ApprovalRules = new[]
        {
            new Aws.Ssm.Inputs.PatchBaselineApprovalRuleArgs
            {
                ApproveAfterDays = 7,
                ComplianceLevel = "HIGH",
                PatchFilters = new[]
                {
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "PRODUCT",
                        Values = new[]
                        {
                            "WindowsServer2016",
                        },
                    },
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "CLASSIFICATION",
                        Values = new[]
                        {
                            "CriticalUpdates",
                            "SecurityUpdates",
                            "Updates",
                        },
                    },
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "MSRC_SEVERITY",
                        Values = new[]
                        {
                            "Critical",
                            "Important",
                            "Moderate",
                        },
                    },
                },
            },
            new Aws.Ssm.Inputs.PatchBaselineApprovalRuleArgs
            {
                ApproveAfterDays = 7,
                PatchFilters = new[]
                {
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "PRODUCT",
                        Values = new[]
                        {
                            "WindowsServer2012",
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ssm.PatchBaseline;
import com.pulumi.aws.ssm.PatchBaselineArgs;
import com.pulumi.aws.ssm.inputs.PatchBaselineGlobalFilterArgs;
import com.pulumi.aws.ssm.inputs.PatchBaselineApprovalRuleArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var production = new PatchBaseline("production", PatchBaselineArgs.builder()
            .name("patch-baseline")
            .description("Patch Baseline Description")
            .approvedPatches(            
                "KB123456",
                "KB456789")
            .rejectedPatches("KB987654")
            .globalFilters(            
                PatchBaselineGlobalFilterArgs.builder()
                    .key("PRODUCT")
                    .values("WindowsServer2008")
                    .build(),
                PatchBaselineGlobalFilterArgs.builder()
                    .key("CLASSIFICATION")
                    .values("ServicePacks")
                    .build(),
                PatchBaselineGlobalFilterArgs.builder()
                    .key("MSRC_SEVERITY")
                    .values("Low")
                    .build())
            .approvalRules(            
                PatchBaselineApprovalRuleArgs.builder()
                    .approveAfterDays(7)
                    .complianceLevel("HIGH")
                    .patchFilters(                    
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("PRODUCT")
                            .values("WindowsServer2016")
                            .build(),
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("CLASSIFICATION")
                            .values(                            
                                "CriticalUpdates",
                                "SecurityUpdates",
                                "Updates")
                            .build(),
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("MSRC_SEVERITY")
                            .values(                            
                                "Critical",
                                "Important",
                                "Moderate")
                            .build())
                    .build(),
                PatchBaselineApprovalRuleArgs.builder()
                    .approveAfterDays(7)
                    .patchFilters(PatchBaselineApprovalRulePatchFilterArgs.builder()
                        .key("PRODUCT")
                        .values("WindowsServer2012")
                        .build())
                    .build())
            .build());

    }
}
resources:
  production:
    type: aws:ssm:PatchBaseline
    properties:
      name: patch-baseline
      description: Patch Baseline Description
      approvedPatches:
        - KB123456
        - KB456789
      rejectedPatches:
        - KB987654
      globalFilters:
        - key: PRODUCT
          values:
            - WindowsServer2008
        - key: CLASSIFICATION
          values:
            - ServicePacks
        - key: MSRC_SEVERITY
          values:
            - Low
      approvalRules:
        - approveAfterDays: 7
          complianceLevel: HIGH
          patchFilters:
            - key: PRODUCT
              values:
                - WindowsServer2016
            - key: CLASSIFICATION
              values:
                - CriticalUpdates
                - SecurityUpdates
                - Updates
            - key: MSRC_SEVERITY
              values:
                - Critical
                - Important
                - Moderate
        - approveAfterDays: 7
          patchFilters:
            - key: PRODUCT
              values:
                - WindowsServer2012

This configuration mixes manual and automatic approval. The approvedPatches and rejectedPatches properties explicitly allow or block specific KBs. The approvalRules property defines filters that automatically approve patches matching criteria like product, classification, and severity. Each rule’s approveAfterDays property delays approval to allow testing. The globalFilters property excludes patches across all rules, such as filtering out low-severity service packs. The complianceLevel property sets the severity when approved patches are missing.

Patch Windows OS and Microsoft applications together

Organizations running Microsoft Office alongside Windows Server need baselines that cover both operating system patches and application updates.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const windowsOsApps = new aws.ssm.PatchBaseline("windows_os_apps", {
    name: "WindowsOSAndMicrosoftApps",
    description: "Patch both Windows and Microsoft apps",
    operatingSystem: "WINDOWS",
    approvalRules: [
        {
            approveAfterDays: 7,
            patchFilters: [
                {
                    key: "CLASSIFICATION",
                    values: [
                        "CriticalUpdates",
                        "SecurityUpdates",
                    ],
                },
                {
                    key: "MSRC_SEVERITY",
                    values: [
                        "Critical",
                        "Important",
                    ],
                },
            ],
        },
        {
            approveAfterDays: 7,
            patchFilters: [
                {
                    key: "PATCH_SET",
                    values: ["APPLICATION"],
                },
                {
                    key: "PRODUCT",
                    values: [
                        "Office 2013",
                        "Office 2016",
                    ],
                },
            ],
        },
    ],
});
import pulumi
import pulumi_aws as aws

windows_os_apps = aws.ssm.PatchBaseline("windows_os_apps",
    name="WindowsOSAndMicrosoftApps",
    description="Patch both Windows and Microsoft apps",
    operating_system="WINDOWS",
    approval_rules=[
        {
            "approve_after_days": 7,
            "patch_filters": [
                {
                    "key": "CLASSIFICATION",
                    "values": [
                        "CriticalUpdates",
                        "SecurityUpdates",
                    ],
                },
                {
                    "key": "MSRC_SEVERITY",
                    "values": [
                        "Critical",
                        "Important",
                    ],
                },
            ],
        },
        {
            "approve_after_days": 7,
            "patch_filters": [
                {
                    "key": "PATCH_SET",
                    "values": ["APPLICATION"],
                },
                {
                    "key": "PRODUCT",
                    "values": [
                        "Office 2013",
                        "Office 2016",
                    ],
                },
            ],
        },
    ])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ssm"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ssm.NewPatchBaseline(ctx, "windows_os_apps", &ssm.PatchBaselineArgs{
			Name:            pulumi.String("WindowsOSAndMicrosoftApps"),
			Description:     pulumi.String("Patch both Windows and Microsoft apps"),
			OperatingSystem: pulumi.String("WINDOWS"),
			ApprovalRules: ssm.PatchBaselineApprovalRuleArray{
				&ssm.PatchBaselineApprovalRuleArgs{
					ApproveAfterDays: pulumi.Int(7),
					PatchFilters: ssm.PatchBaselineApprovalRulePatchFilterArray{
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("CLASSIFICATION"),
							Values: pulumi.StringArray{
								pulumi.String("CriticalUpdates"),
								pulumi.String("SecurityUpdates"),
							},
						},
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("MSRC_SEVERITY"),
							Values: pulumi.StringArray{
								pulumi.String("Critical"),
								pulumi.String("Important"),
							},
						},
					},
				},
				&ssm.PatchBaselineApprovalRuleArgs{
					ApproveAfterDays: pulumi.Int(7),
					PatchFilters: ssm.PatchBaselineApprovalRulePatchFilterArray{
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("PATCH_SET"),
							Values: pulumi.StringArray{
								pulumi.String("APPLICATION"),
							},
						},
						&ssm.PatchBaselineApprovalRulePatchFilterArgs{
							Key: pulumi.String("PRODUCT"),
							Values: pulumi.StringArray{
								pulumi.String("Office 2013"),
								pulumi.String("Office 2016"),
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var windowsOsApps = new Aws.Ssm.PatchBaseline("windows_os_apps", new()
    {
        Name = "WindowsOSAndMicrosoftApps",
        Description = "Patch both Windows and Microsoft apps",
        OperatingSystem = "WINDOWS",
        ApprovalRules = new[]
        {
            new Aws.Ssm.Inputs.PatchBaselineApprovalRuleArgs
            {
                ApproveAfterDays = 7,
                PatchFilters = new[]
                {
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "CLASSIFICATION",
                        Values = new[]
                        {
                            "CriticalUpdates",
                            "SecurityUpdates",
                        },
                    },
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "MSRC_SEVERITY",
                        Values = new[]
                        {
                            "Critical",
                            "Important",
                        },
                    },
                },
            },
            new Aws.Ssm.Inputs.PatchBaselineApprovalRuleArgs
            {
                ApproveAfterDays = 7,
                PatchFilters = new[]
                {
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "PATCH_SET",
                        Values = new[]
                        {
                            "APPLICATION",
                        },
                    },
                    new Aws.Ssm.Inputs.PatchBaselineApprovalRulePatchFilterArgs
                    {
                        Key = "PRODUCT",
                        Values = new[]
                        {
                            "Office 2013",
                            "Office 2016",
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ssm.PatchBaseline;
import com.pulumi.aws.ssm.PatchBaselineArgs;
import com.pulumi.aws.ssm.inputs.PatchBaselineApprovalRuleArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var windowsOsApps = new PatchBaseline("windowsOsApps", PatchBaselineArgs.builder()
            .name("WindowsOSAndMicrosoftApps")
            .description("Patch both Windows and Microsoft apps")
            .operatingSystem("WINDOWS")
            .approvalRules(            
                PatchBaselineApprovalRuleArgs.builder()
                    .approveAfterDays(7)
                    .patchFilters(                    
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("CLASSIFICATION")
                            .values(                            
                                "CriticalUpdates",
                                "SecurityUpdates")
                            .build(),
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("MSRC_SEVERITY")
                            .values(                            
                                "Critical",
                                "Important")
                            .build())
                    .build(),
                PatchBaselineApprovalRuleArgs.builder()
                    .approveAfterDays(7)
                    .patchFilters(                    
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("PATCH_SET")
                            .values("APPLICATION")
                            .build(),
                        PatchBaselineApprovalRulePatchFilterArgs.builder()
                            .key("PRODUCT")
                            .values(                            
                                "Office 2013",
                                "Office 2016")
                            .build())
                    .build())
            .build());

    }
}
resources:
  windowsOsApps:
    type: aws:ssm:PatchBaseline
    name: windows_os_apps
    properties:
      name: WindowsOSAndMicrosoftApps
      description: Patch both Windows and Microsoft apps
      operatingSystem: WINDOWS
      approvalRules:
        - approveAfterDays: 7
          patchFilters:
            - key: CLASSIFICATION
              values:
                - CriticalUpdates
                - SecurityUpdates
            - key: MSRC_SEVERITY
              values:
                - Critical
                - Important
        - approveAfterDays: 7
          patchFilters:
            - key: PATCH_SET
              values:
                - APPLICATION
            - key: PRODUCT
              values:
                - Office 2013
                - Office 2016

The operatingSystem property scopes the baseline to Windows. Multiple approval rules target different patch sets: one for OS patches filtered by classification and severity, another for Microsoft Office products. The PATCH_SET filter distinguishes between operating system patches and application patches.

Configure custom patch repositories for Amazon Linux

Teams managing Amazon Linux instances sometimes need to point Patch Manager at custom or internal repositories.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const al201709 = new aws.ssm.PatchBaseline("al_2017_09", {
    approvalRules: [{}],
    name: "Amazon-Linux-2017.09",
    description: "My patch repository for Amazon Linux 2017.09",
    operatingSystem: "AMAZON_LINUX",
    sources: [{
        name: "My-AL2017.09",
        products: ["AmazonLinux2017.09"],
        configuration: `[amzn-main]
name=amzn-main-Base
mirrorlist=http://repo./awsregion./awsdomain//releasever/main/mirror.list
mirrorlist_expire=300
metadata_expire=300
priority=10
failovermethod=priority
fastestmirror_enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
enabled=1
retries=3
timeout=5
report_instanceid=yes
`,
    }],
});
import pulumi
import pulumi_aws as aws

al201709 = aws.ssm.PatchBaseline("al_2017_09",
    approval_rules=[{}],
    name="Amazon-Linux-2017.09",
    description="My patch repository for Amazon Linux 2017.09",
    operating_system="AMAZON_LINUX",
    sources=[{
        "name": "My-AL2017.09",
        "products": ["AmazonLinux2017.09"],
        "configuration": """[amzn-main]
name=amzn-main-Base
mirrorlist=http://repo./$awsregion./$awsdomain//$releasever/main/mirror.list
mirrorlist_expire=300
metadata_expire=300
priority=10
failovermethod=priority
fastestmirror_enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
enabled=1
retries=3
timeout=5
report_instanceid=yes
""",
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ssm"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ssm.NewPatchBaseline(ctx, "al_2017_09", &ssm.PatchBaselineArgs{
			ApprovalRules: ssm.PatchBaselineApprovalRuleArray{
				&ssm.PatchBaselineApprovalRuleArgs{},
			},
			Name:            pulumi.String("Amazon-Linux-2017.09"),
			Description:     pulumi.String("My patch repository for Amazon Linux 2017.09"),
			OperatingSystem: pulumi.String("AMAZON_LINUX"),
			Sources: ssm.PatchBaselineSourceArray{
				&ssm.PatchBaselineSourceArgs{
					Name: pulumi.String("My-AL2017.09"),
					Products: pulumi.StringArray{
						pulumi.String("AmazonLinux2017.09"),
					},
					Configuration: pulumi.String(`[amzn-main]
name=amzn-main-Base
mirrorlist=http://repo./$awsregion./$awsdomain//$releasever/main/mirror.list
mirrorlist_expire=300
metadata_expire=300
priority=10
failovermethod=priority
fastestmirror_enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
enabled=1
retries=3
timeout=5
report_instanceid=yes
`),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var al201709 = new Aws.Ssm.PatchBaseline("al_2017_09", new()
    {
        ApprovalRules = new[]
        {
            null,
        },
        Name = "Amazon-Linux-2017.09",
        Description = "My patch repository for Amazon Linux 2017.09",
        OperatingSystem = "AMAZON_LINUX",
        Sources = new[]
        {
            new Aws.Ssm.Inputs.PatchBaselineSourceArgs
            {
                Name = "My-AL2017.09",
                Products = new[]
                {
                    "AmazonLinux2017.09",
                },
                Configuration = @"[amzn-main]
name=amzn-main-Base
mirrorlist=http://repo./$awsregion./$awsdomain//$releasever/main/mirror.list
mirrorlist_expire=300
metadata_expire=300
priority=10
failovermethod=priority
fastestmirror_enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
enabled=1
retries=3
timeout=5
report_instanceid=yes
",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ssm.PatchBaseline;
import com.pulumi.aws.ssm.PatchBaselineArgs;
import com.pulumi.aws.ssm.inputs.PatchBaselineApprovalRuleArgs;
import com.pulumi.aws.ssm.inputs.PatchBaselineSourceArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var al201709 = new PatchBaseline("al201709", PatchBaselineArgs.builder()
            .approvalRules(PatchBaselineApprovalRuleArgs.builder()
                .build())
            .name("Amazon-Linux-2017.09")
            .description("My patch repository for Amazon Linux 2017.09")
            .operatingSystem("AMAZON_LINUX")
            .sources(PatchBaselineSourceArgs.builder()
                .name("My-AL2017.09")
                .products("AmazonLinux2017.09")
                .configuration("""
[amzn-main]
name=amzn-main-Base
mirrorlist=http://repo./$awsregion./$awsdomain//$releasever/main/mirror.list
mirrorlist_expire=300
metadata_expire=300
priority=10
failovermethod=priority
fastestmirror_enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
enabled=1
retries=3
timeout=5
report_instanceid=yes
                """)
                .build())
            .build());

    }
}
resources:
  al201709:
    type: aws:ssm:PatchBaseline
    name: al_2017_09
    properties:
      approvalRules:
        - {}
      name: Amazon-Linux-2017.09
      description: My patch repository for Amazon Linux 2017.09
      operatingSystem: AMAZON_LINUX
      sources:
        - name: My-AL2017.09
          products:
            - AmazonLinux2017.09
          configuration: |
            [amzn-main]
            name=amzn-main-Base
            mirrorlist=http://repo./$awsregion./$awsdomain//$releasever/main/mirror.list
            mirrorlist_expire=300
            metadata_expire=300
            priority=10
            failovermethod=priority
            fastestmirror_enabled=0
            gpgcheck=1
            gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-ga
            enabled=1
            retries=3
            timeout=5
            report_instanceid=yes            

The sources property defines alternate patch repositories for Linux instances. The configuration property contains yum repository configuration syntax, including mirror lists and GPG keys. The products property scopes the source to specific Amazon Linux versions. This allows you to use internal mirrors or custom repositories instead of AWS-managed sources.

Beyond these examples

These snippets focus on specific patch baseline features: explicit patch approval and rejection, rule-based automatic approval with filters, and custom patch repositories. They’re intentionally minimal rather than full patch management solutions.

The examples may reference pre-existing infrastructure such as SSM-managed EC2 instances or on-premises servers, and custom yum repositories for Amazon Linux examples. They focus on defining patch policies rather than applying them to instances.

To keep things focused, common patch management patterns are omitted, including:

  • Patch group associations (requires separate PatchGroup resource)
  • Maintenance window scheduling (requires MaintenanceWindow resources)
  • Compliance reporting and monitoring setup
  • Non-security update handling (approvedPatchesEnableNonSecurity)

These omissions are intentional: the goal is to illustrate how each baseline feature is wired, not provide drop-in patch management modules. See the SSM Patch Baseline resource reference for all available configuration options.

Let's configure AWS Systems Manager Patch Baselines

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration Requirements
Do I need to specify both approvedPatches and approvalRule?
No, you must specify at least one but cannot specify both. Choose either approvedPatches for an explicit patch list or approvalRule for rule-based selection.
Can I change the operating system after creating a patch baseline?
No, the operatingSystem property is immutable. To change the operating system, you must recreate the patch baseline.
Patch Selection & Filtering
What's the difference between approvedPatches and approvalRule?
approvedPatches is an explicit list of patch IDs (e.g., KB123456), while approvalRule uses filters to automatically select patches based on criteria like classification, severity, or product.
How do I filter patches by severity or classification?
Use globalFilters to exclude patches or patchFilters within approvalRules to include patches. Specify keys like MSRC_SEVERITY (Critical, Important, Moderate) or CLASSIFICATION (CriticalUpdates, SecurityUpdates).
How do I patch Microsoft Office applications?
Use approvalRules with a patchFilter where PATCH_SET is APPLICATION and PRODUCT includes Office versions (e.g., Office 2013, Office 2016).
What happens to rejected patches?
Configure rejectedPatchesAction to either BLOCK (prevent installation) or ALLOW_AS_DEPENDENCY (allow if required by approved patches).
Operating System Specifics
How do I include non-security updates for Linux instances?
Set approvedPatchesEnableNonSecurity to true. This property applies to Linux instances only.
Can I use an alternate patch repository for Linux?
Yes, configure sources with repository details (name, products, and configuration). This applies to Linux instances only.
What's availableSecurityUpdatesComplianceStatus used for?
It indicates compliance status for managed nodes with available but unapproved security patches. This is supported for Windows Server managed nodes only. Valid values are COMPLIANT and NON_COMPLIANT.
Limits & Constraints
What are the limits on approval rules and global filters?
You can specify up to 10 approval rules and up to 4 global filters per patch baseline.

Using a different cloud?

Explore security guides for other cloud providers: