This repository provides a Pulumi-based solution to deploy and manage AWS Systems Manager (SSM) Documents across one or more AWS regions. It includes validation logic to ensure SSM document payloads comply with approved schemas, and automatically shares these documents with specified AWS accounts.
Information and Known issues: https://ollion.atlassian.net/wiki/x/CYA3-w
- Overview
- Prerequisites
- Installation
- Configuration
- Usage
- SSM Documents Provided
- Code Structure
- Testing
- Contributing
- License
This repository provides a modular, extensible framework for deploying AWS Systems Manager (SSM) Documents across multiple AWS regions using Pulumi ESC with OIDC authentication. The solution follows modern software engineering principles with a clean separation of concerns across multiple components:
- Templating: Standardized document templates with consistent structure and behavior
- Validation: Comprehensive validation against AWS SSM schema requirements
- Script Library: Reusable, cross-platform script templates for common operations
- Deployment: Pulumi component resources for managing multi-region deployments
The project seamlessly integrates with Pulumi ESC by separating:
- Environment: Stacks managed via ESC environments
- Secrets: Sensitive values stored and retrieved through ESC secret management
- Config: Declarative settings in
Pulumi.<stack>.yamlfor region selection and account sharing
On each run, the project deploys a suite of SSM Documents—ranging from agent management to user administration tools—to your configured regions, sharing them with specified AWS accounts.
- Pulumi CLI https://www.pulumi.com/docs/iac/download-install/
- ESC CLI https://www.pulumi.com/docs/esc/download-install/
- Python >= 3.7
- AWS Credentials configured locally (via
~/.aws/credentials, environment variables, or IAM role) - AWS OIDC Provider configured for Pulumi ESC
This repository includes a CloudFormation template (CloudFormation template/Pulumi-OIDC.yaml) to quickly set up the required AWS OIDC integration for Pulumi ESC, which you can deploy via the AWS Console or CLI.
-
Clone the repository:
git clone <repo-url> && cd <repo-dir>
-
Install Python dependencies:
pip install --upgrade pip pip install -r requirements.txt
-
Log in to Pulumi ESC:
esc login
Define your stack configuration in Pulumi.<stack>.yaml at the project root:
config:
enabled_regions:
- us-east-1
- eu-central-1
- ap-southeast-2
accountIds:
- "1234567890"Important configuration details:
- The default region is determined by your Pulumi/AWS environment settings and is where the Pulumi program runs
- The enabled_regions list specifies all AWS regions where the SSM documents will be deployed
- The accountIds list contains AWS account IDs that the documents will be shared with (in addition to the account where they're being deployed)
For example, if your Pulumi is running in account 987654321 and you've specified the configuration above:
- SSM documents will be deployed to
us-east-1,eu-central-1, andap-southeast-2in account987654321 - Each document will be shared with account
1234567890, allowing that account to use the documents without creating its own copies
Secrets can be managed using pulumi env set and referenced in your configuration as needed.
Deploy all configured SSM Documents:
# List current environment
pulumi env ls
# Run in selected environment
pulumi env run <environment-name> -- pulumi up --yesDestroy all deployed resources:
pulumi env run <environment-name> -- pulumi destroy --yesThe following SSM Documents are automatically created in every region listed under enabled_regions. Each name includes a region-specific <code> suffix (e.g., apse2 for ap-southeast-2).
| Document Name | Description | Parameters |
|---|---|---|
NewRelic-Agent-Install-<code> |
Install & configure the New Relic Infrastructure Agent | apiKey, accountId, region, displayName, enableLogForwarding, enableProcessMetrics |
NewRelic-Agent-Upgrade-<code> |
Upgrade New Relic Infrastructure Agent (Linux & Windows) | None |
NewRelic-Agent-Uninstall-<code> |
Remove New Relic Infrastructure Agent | None |
Create-Local-User-Windows-<code> |
Create a local Windows user with secure random password | username, fullName, userDescription, group |
Reset-Local-User-Passwords-Windows-<code> |
Reset Windows local-user passwords (logs new passwords) | userNames: Comma-separated list of Windows usernames |
Check-Local-User-Expiration-Windows-<code> |
Report Windows local-user password expiry | None |
Create-Local-User-Linux-<code> |
Create a Linux user and store password in Parameter Store | username, group, parameterPrefix, expirationHours |
Delete-Local-Users-Linux-<code> |
Remove one or more Linux users | usernames: Comma-separated list, deleteHome: true/false |
Create-Passwordless-User-Linux-<code> |
Create Linux user with SSH key + sudo NOPASSWD | username, secondaryGroup, parameterPrefix, expirationHours, keyType: ed25519/rsa |
Upgrade-Packages-Linux-<code> |
Upgrade specific packages (latest or security-only) | packages: Comma-separated list, updateType: latest/security, cves: Comma-separated CVE IDs |
Disk-Cleanup-Windows-<code> |
Automated disk cleanup & component cleanup on Windows | None |
Check-Local-User-Expiration-Linux-<code> |
List Linux local users & password expiry | excludedUsers: Comma-separated list, minimumUid: Minimum UID to check |
├── __main__.py # Entry point: orchestrates multi-region deployment
├── validator.py # SSM Document validation logic
├── script_library.py # Reusable script templates for documents
├── document_templates.py # Standardized SSM document payload definitions
├── ssm_component.py # Pulumi component for SSM document deployment
├── CloudFormation template/ # Templates for infrastructure setup
│ └── Pulumi-OIDC.yaml # CloudFormation template for AWS OIDC setup
├── requirements.txt # Python dependencies
└── Pulumi.<stack>.yaml # Stack configuration: enabled_regions, accountIds
To validate changes:
-
Run a Pulumi dry run:
pulumi preview # or pulumi up --dry-run -
Ensure SSM document payloads pass schema validation during the run.
We welcome contributions! Please follow these guidelines:
-
Fork this repository.
-
Create a feature branch:
git checkout -b feature/your-feature
-
Implement your changes and update documentation as needed.
-
Commit with a descriptive message:
git commit -m "feat: add new SSM document for X" -
Push your branch to your fork:
git push origin feature/your-feature
-
Open a Pull Request against the
mainbranch, describing your changes.
To add a new SSM document to the deployment, follow these steps:
-
Create Script Templates (if needed)
-
Open
script_library.py -
Add a new static method to the
SsmScriptLibraryclass with your script content -
Ensure your script handles different OS versions and includes proper error handling
-
Example:
@staticmethod def my_new_script() -> List[str]: """ Description of what this script does. Returns: List[str]: Script commands as a line-by-line list """ return [ "#!/usr/bin/env bash", "set -euo pipefail", "# Your script commands here", "echo 'Hello from my new script'", ]
-
-
Define Document Template
-
Open
document_templates.py -
Add a new static method to the
SsmDocumentTemplatesclass -
Create your document payload with appropriate schema, parameters and steps
-
Reference your script template from
SsmScriptLibraryif needed -
Example:
@staticmethod def my_new_document() -> Dict[str, Any]: """ Create an SSM document for my new operation. Description of what this document does. Returns: Dict[str, Any]: A complete SSM document template as a dictionary """ return { "schemaVersion": "2.2", "description": "My new SSM document", "parameters": { "myParam": { "type": "String", "description": "Description of parameter" } }, "mainSteps": [ { "name": "RunMyScript", "action": "aws:runShellScript", "precondition": {"StringEquals": ["platformType", "Linux"]}, "inputs": { "timeoutSeconds": 300, "runCommand": SsmScriptLibrary.my_new_script() } } ] }
-
-
Register Document in Component
-
Open
ssm_component.py -
Find the
_create_documentsmethod in theSsmDocsclass -
Add your document to the
document_templateslist:document_templates = [ # Existing documents... ("My-New-Document", SsmDocumentTemplates.my_new_document), ]
-
-
Update Documentation
-
Add your document to the SSM Documents table in this README.md:
| `My-New-Document-<code>` | Description of what your document does | `myParam`: Description of parameter |
-
-
Test Your Addition
- Run
pulumi previewto ensure your document passes validation - Check for any issues in the validator output
- Test the deployed document in AWS if possible
- Run
Your new SSM document will now be automatically deployed to all configured regions along with the existing documents.
This project is released under the MIT License.