https://github.com/areguera/terraform-aws-ssm
Terraform module to compose AWS Systems Manager (SSM) configurations
https://github.com/areguera/terraform-aws-ssm
aws-ssm patch-management state-management terraform-module
Last synced: 5 months ago
JSON representation
Terraform module to compose AWS Systems Manager (SSM) configurations
- Host: GitHub
- URL: https://github.com/areguera/terraform-aws-ssm
- Owner: areguera
- License: apache-2.0
- Created: 2022-05-23T21:32:06.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-02-18T12:50:03.000Z (almost 2 years ago)
- Last Synced: 2025-04-24T09:40:46.165Z (8 months ago)
- Topics: aws-ssm, patch-management, state-management, terraform-module
- Language: HCL
- Homepage: https://registry.terraform.io/modules/areguera/ssm/aws/
- Size: 135 KB
- Stars: 9
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# terraform-aws-ssm
Terraform module to compose [AWS Systems Manager (SSM)](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) configurations.
## Usage
```hcl=
module "ssm" {
source = "areguera/ssm/aws"
name = var.name
operating_system = "AMAZON_LINUX_2"
approved_patches_compliance_level = "CRITICAL"
approved_patches_enable_non_security = false
approval_rules = [{
approve_after_days = 7
compliance_level = "CRITICAL"
enable_non_security = false
patch_filters = [
{ key = "PRODUCT", values = ["AmazonLinux2"] },
{ key = "CLASSIFICATION", values = ["Security", "Bugfix"] },
{ key = "SEVERITY", values = ["Critical", "Important"] }
]
}]
maintenance_window = {
enabled = true
schedule = "cron(0 9 */7 * ?)"
schedule_timezone = "UTC"
cutoff = 0
duration = 1
}
}
```
## Patch baseline
This module creates one patch baseline named `${var.name}`. this patch baseline
applies to all Amazon Linux 2 EC2 instances tagged with the `Patch Group` tag
name and value `${var.name}`. These instances will approve all operating system
patches that are classified as "Security" and have a severity level of
"Critical" or "Important". Patches are auto-approved seven days after release.
Also approves all patches with a classification of "Bugfix" seven days after
release.
```
* * * * *
| | | | |
------>|------>|------>|------>|------>|
| | | | |
* * * * *
```
This module configures the `${var.name}` patch baseline to reboot instances
during maintenance window automatically, if needed. To prevent down-time, you
need to design your infrastructure to keep your application up-and-running in
spite of system reboots or unexpected application failures because of patching
itself. For example, you could use the SSM configuration this module provides
in combination with other AWS technologies like load balancer and auto-scaling
groups with the health checks enabled and properly configured on them.
To know more about patch baseline, see [AWS Systems Manager Patch Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-patch.html) documentation.
## Maintenance window
This module creates a maintenance window that runs every seven days at 9 AM
UTC. This maintenance window is configured with two tasks that run in order.
The first task installs new patches and reboots the target operating systems if
needed. The second task applies configuration playbooks on target operating
system to grantee their desired state after patching. The second task also
executes simple tests to validate the application is running as expected. In
case any of these two tasks fail, the maintenance window will fail and the
patching action stops from being propagated to remaining target systems.
This module schedules the maintenance window to run every seven days at 9 A.M.
The schedule was set in alignment with the patch baseline approval time frame,
which is also seven days. So, that's the moment in time when system patching
will happen.
This module only supports one maintenance window per module instantiation. To
create more than one maintenance window for your infrastructure, create one
unique configuration for each one of them. Avoid one unique configuration with
several maintenance windows inside if possible. Having several configurations
with only one maintenance window allows you to manage different configurations
easier. For example, in cases where each configuration represents a specific
level of risk (e.g., dev, stage, prod).
To know more about maintenance window, see [AWS Systems Manager Maintenance Windows](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-maintenance.html) documentation.
## Associations
This module creates the following associations:
| Name | Recurrency | Description |
| ------------------------------------- | ---------- | ----------- |
| `${var.name}-UpdateSSMAgent` | 14 days | Update SSM agent when a new version is available. |
| `${var.name}-ApplyAnsiblePlaybooks` | 30 minutes | Apply ansible playbooks available in `${path.root}/ansible/` directory. |
| `${var.name}-GatherSoftwareInventory` | 30 minutes | Collect system information. |
| `${var.name}-RunPatchBaseline` | 24 hours | Applies the `${var.name}` patch baseline in Scan mode to identify available patching. |
To know more about associations, see [AWS System Manger State Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-patch.html) documentation.
## Documents
This module creates the `${var.name}-ApplyAnsiblePlaybooks` document that you
can use to download ansible playbooks from a *private* S3 bucket and apply them
on SSM managed nodes. This document is a modified version of the
`AWS-ApplyAnsiblePlaybooks` document, which doesn't support private
communication with an S3 bucket.
The `${var.name}-ApplyAnsiblePlaybooks` document synchronizes the
`${path.root}/ansible/` directory structure from S3 to
`/opt/${var.name}-ssm/ansible` directory, locally, in the SSM managed node file
system, where the associations or maintenance window tasks are configured to
run at. Finally, the document creates a list of all playbooks found in the
first level of `/opt/${var.name}-ssm/ansible` directory, and executes them one
by one, in alphabetic order, using the ansible-playbook command.
To know more about documents, see [AWS Systems Manager documents](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-ssm-docs.html) documentation.
## Desired state
This module implements the desired state of SSM managed nodes using the ansible
playbooks you provide in the `${path.root}/ansible/` directory. To apply these
playbooks on SSM managed nodes, the `terraform-aws-ssm` module deploys a
private S3 bucket named `${var.name}-ssm`, uploads the `${path.root}/ansible/`
directory up to it, and uses the `${var.name}-ApplyAnsiblePlaybooks` document
to apply them, when it is executed from either associations or maintenance
window tasks.
## Examples
* [Simple SSM configurations](https://github.com/areguera/terraform-aws-ssm/tree/main/examples/simple)
## Requirements
| Name | Version |
|------|---------|
| [aws](#requirement\_aws) | ~> 4.0 |
## Providers
| Name | Version |
|------|---------|
| [aws](#provider\_aws) | ~> 4.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 3.0 |
## Resources
| Name | Type |
|------|------|
| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_policy.AmazonEC2SSMCloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.AmazonEC2SSMS3Logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.AmazonEC2SSMS3Playbooks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.AmazonEC2SSMCloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.AmazonEC2SSMS3Logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.AmazonEC2SSMS3Playbooks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.AmazonSSMManagedInstanceCore](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.AmazonSSMPatchAssociation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_s3_object.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
| [aws_ssm_association.ApplyAnsiblePlaybooks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_association) | resource |
| [aws_ssm_association.GatherSoftwareInventory](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_association) | resource |
| [aws_ssm_association.RunPatchBaseline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_association) | resource |
| [aws_ssm_association.UpdateSSMAgent](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_association) | resource |
| [aws_ssm_document.ApplyAnsiblePlaybooks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_document) | resource |
| [aws_ssm_maintenance_window.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_maintenance_window) | resource |
| [aws_ssm_maintenance_window_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_maintenance_window_target) | resource |
| [aws_ssm_maintenance_window_task.ApplyAnsiblePlaybooks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_maintenance_window_task) | resource |
| [aws_ssm_maintenance_window_task.SystemPatches](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_maintenance_window_task) | resource |
| [aws_ssm_patch_baseline.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_patch_baseline) | resource |
| [aws_ssm_patch_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_patch_group) | resource |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [approval\_rules](#input\_approval\_rules) | (Required) Specify the set of rules used to include patches in the baseline. Up to 10 approval rules can be specified. |
list(object({
approve_after_days = number
compliance_level = string
enable_non_security = bool
patch_filters = list(object({
key = string
values = list(string)
}))
})) | n/a | yes |
| [approved\_patches\_compliance\_level](#input\_approved\_patches\_compliance\_level) | (Optional) Defines the compliance level for approved patches. This means that if an approved patch is reported as missing, this is the severity of the compliance violation. Valid compliance levels include the following: CRITICAL, HIGH, MEDIUM, LOW, INFORMATIONAL, UNSPECIFIED. | `string` | `"UNSPECIFIED"` | no |
| [approved\_patches\_enable\_non\_security](#input\_approved\_patches\_enable\_non\_security) | (Optional) Indicates whether the list of approved patches includes non-security updates that should be applied to the instances. | `bool` | `false` | no |
| [description](#input\_description) | (Optional) The project description. | `string` | `""` | no |
| [maintenance\_window](#input\_maintenance\_window) | (Required) Specify the set of rules used to configure the maintenance window. | object({
schedule = string
schedule_timezone = string
cutoff = number
duration = number
enabled = bool
}) | n/a | yes |
| [max\_concurrency](#input\_max\_concurrency) | (Optional) Specify the number of managed nodes that run a command simultaneously. Posible values can be integers (e.g., '5', '10') or percentages (e.g., '10%', '20%'). In both cases the values must be passed as string. | `string` | `"10%"` | no |
| [max\_errors](#input\_max\_errors) | (Optional) Specify how many errors are allowed before the system stops sending the command to additional managed nodes. Posible values can be integers (e.g., '5', '10') or percentages (e.g., '10%', '20%'). In both cases the values must be passed as string. | `string` | `"1"` | no |
| [name](#input\_name) | (Required) The project name. This value is prefixed to SSM configuration resources. | `string` | n/a | yes |
| [operating\_system](#input\_operating\_system) | (Optional) Defines the operating system the patch baseline applies to. Supported operating systems include AMAZON\_LINUX\_2. | `string` | `"AMAZON_LINUX_2"` | no |
## Outputs
| Name | Description |
|------|-------------|
| [iam\_instantace\_profile\_name](#output\_iam\_instantace\_profile\_name) | n/a |