├── .github ├── ISSUES_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CONTRIBUTING.md ├── Community ├── 101-SSH-PowerShell-Remoting │ ├── README.md │ └── install.ps1 ├── Compliance │ └── README.md ├── Documents │ ├── Automation │ │ └── README.md │ └── Command │ │ └── README.md ├── Inventory │ └── README.md └── Scripts │ └── README.md ├── Compliance ├── InSpec │ ├── PortCheck │ │ ├── Readme.md │ │ ├── controls │ │ │ ├── linux_ssh_port_check.rb │ │ │ └── windows_rdp_port_check.rb │ │ └── inspec.yml │ └── Readme.md └── README.md ├── Documents ├── Automation │ ├── ASGChangeStandbyState │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── DeployLambda.yml │ │ │ ├── Lambdas │ │ │ │ └── change_asg_state.py │ │ │ └── aws-ASGChangeStandbyState.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── ASG.yml │ │ │ ├── __init__.py │ │ │ └── tests.py │ ├── ASGChangeStandbyStateWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── aws-ASGEnterStandbyWithApproval.json │ │ │ └── aws-ASGExitStandbyWithApproval.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── ASG.yml │ │ │ ├── __init__.py │ │ │ └── tests.py │ ├── AttachEBSVolumes │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── CloudFormationAttachVolume.yml │ │ │ └── aws-AttachEBSVolume.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── AttachIAMToInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── AttachIAMToInstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── attach_iam_to_instance.py │ │ │ └── aws-AttachIAMToInstance.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ ├── TestAssociated.yml │ │ │ └── TestNotAssociated.yml │ │ │ ├── test_iam_already_associated.py │ │ │ └── test_iam_not_associated.py │ ├── ConfigureCloudWatchOnEC2Instance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── ConfigureCloudWatchOnEC2InstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── configure_cloudwatch_on_ec2_instance.py │ │ │ └── aws-ConfigureCloudWatchOnEC2Instance.json │ │ ├── Makefile │ │ ├── README.md │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ ├── test_document_case_disabled.py │ │ │ └── test_document_case_enabled.py │ ├── CopySnapshot │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── CopySnapshotCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── copy_snapshot.py │ │ │ └── aws-CopySnapshot.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── CreateEKSClusterWithNodegroup │ │ ├── Design │ │ │ └── Design.md │ │ ├── Documents │ │ │ └── aws-CreateEKSClusterWithNodegroup.yml │ │ └── Tests │ │ │ └── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ ├── CreateImage │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-CreateImage.json │ │ ├── Makefile │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── CreateSnapshot │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── CreateSnapshotCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── create_snapshot.py │ │ │ └── aws-CreateSnapshot.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── DeleteCloudFormation │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-DeleteCloudFormation.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── DeleteCloudFormationWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-DeleteCloudFormationWithApproval.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── DeleteImage │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-DeleteImage.json │ │ ├── Makefile │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── DeleteSnapshot │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── DeleteSnapshotCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── delete_snapshot.py │ │ │ └── aws-DeleteSnapshot.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── DetachEBSVolumes │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── DetachVolumeCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── detach_volume.py │ │ │ └── aws-DetachEBSVolume.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ ├── test_document.py │ │ │ └── test_mounted.py │ ├── EnableS3BucketKeys │ │ ├── Design │ │ │ └── Design.md │ │ ├── Documents │ │ │ └── aws-EnableS3BucketKeys.yml │ │ └── Tests │ │ │ └── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ ├── EnableSQSEncryption │ │ ├── Design │ │ │ └── Design.md │ │ ├── Documents │ │ │ └── aws-EnableSQSEncryption.yml │ │ └── Tests │ │ │ └── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ ├── EncryptRootVolume │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-encryptrootvolume.json │ │ ├── Makefile │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── ManagedInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── CreateManagedInstance.yml │ │ │ ├── Lambdas │ │ │ │ ├── __init__.py │ │ │ │ ├── collect_info.py │ │ │ │ ├── create_instance_profile.py │ │ │ │ ├── create_security_group.py │ │ │ │ └── subnet_info.py │ │ │ ├── aws-CreateManagedInstance.json │ │ │ ├── aws-CreateManagedInstanceWithApproval.json │ │ │ ├── aws-CreateManagedLinuxInstance.json │ │ │ └── aws-CreateManagedWindowsInstance.json │ │ ├── Output │ │ │ ├── aws-CreateManagedLinuxInstance.json │ │ │ ├── aws-CreateManagedLinuxInstanceWithApproval.json │ │ │ ├── aws-CreateManagedWindowsInstance.json │ │ │ └── aws-CreateManagedWindowsInstanceWithApproval.json │ │ ├── Setup │ │ │ └── create_document.py │ │ ├── Tests │ │ │ ├── __init__.py │ │ │ ├── lib │ │ │ │ ├── __init__.py │ │ │ │ └── cfnresponse.py │ │ │ ├── managedinstanceutil.py │ │ │ ├── test_approval_document.py │ │ │ ├── test_collect_info.py │ │ │ ├── test_create_instance_profile.py │ │ │ ├── test_create_security_group.py │ │ │ └── test_document.py │ │ └── makefile │ ├── PatchWindowsInASG │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-PatchWindowsInASG.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── ASG.yml │ │ │ └── tests.py │ ├── Readme.md │ ├── RebootRds │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── RebootRdsInstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ ├── reboot_rds_instance.py │ │ │ │ └── wait_rds_instance.py │ │ │ └── aws-RebootRdsInstance.json │ │ ├── Makefile │ │ ├── README.md │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── ResizeInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── ResizeInstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── resize_instance.py │ │ │ └── aws-ResizeInstance.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ └── test_document.py │ ├── RestartInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-RestartEC2Instance.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── RestartInstanceWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-RestartEC2Instance.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── StartInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-StartEC2Instance.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── ThreeInstances.yml │ │ │ └── tests.py │ ├── StartInstanceWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-StartEC2InstanceWithApproval.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstancesWithSNS.yml │ │ │ └── tests.py │ ├── StartRdsInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── StartRdsInstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ ├── start_rds_instance.py │ │ │ │ └── wait_rds_instance.py │ │ │ └── aws-StartRdsInstance.json │ │ ├── Makefile │ │ ├── README.md │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ ├── test_document.py │ │ │ └── test_document_case_available.py │ ├── StopInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-StopEC2Instance.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── StopInstanceWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-StopEC2InstanceWithApproval.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstancesWithSNS.yml │ │ │ └── tests.py │ ├── StopRdsInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── StopRdsInstanceCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ ├── stop_rds_instance.py │ │ │ │ └── wait_rds_instance.py │ │ │ └── aws-StopRdsInstance.json │ │ ├── Makefile │ │ ├── README.md │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TestTemplate.yml │ │ │ ├── test_document.py │ │ │ └── test_document_case_stopped_rds.py │ ├── TerminateInstance │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-TerminateEC2Instance.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── TerminateInstanceWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ └── aws-TerminateEC2InstanceWithApproval.json │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ └── TwoInstances.yml │ │ │ └── tests.py │ ├── Testing │ │ ├── __init__.py │ │ ├── defaults.cfg │ │ └── ssm_testing.py │ ├── UpdateCloudFormationTemplate │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── UpdateCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── update_cf_template.py │ │ │ └── aws-UpdateCloudFormationTemplate.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ ├── TestTemplate.yml │ │ │ └── TestUpdateTemplate.yml │ │ │ └── test_document.py │ ├── UpdateCloudFormationWithApproval │ │ ├── Design │ │ │ ├── Design.md │ │ │ └── schema.json │ │ ├── Documents │ │ │ ├── CloudFormationTemplates │ │ │ │ └── UpdateCFTemplate.yml │ │ │ ├── Lambdas │ │ │ │ └── update_cf_template.py │ │ │ └── aws-UpdateCloudFormationWithApproval.json │ │ ├── Makefile │ │ ├── Setup │ │ │ └── create_document.py │ │ └── Tests │ │ │ ├── CloudFormationTemplates │ │ │ ├── TestTemplate.yml │ │ │ └── TestUpdateTemplate.yml │ │ │ └── test_document.py │ └── requirements.txt └── Command │ ├── ConfigureAgentLogsUploadToCloudwatch │ ├── ConfigureAgentLogsUploadToCloudwatch.json │ └── README.md │ └── README.md ├── Inventory └── README.md ├── LICENSE ├── NOTICE.txt └── README.md /.github/ISSUES_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Description: 2 | 3 | Resource causing Issue: 4 | 5 | Steps to reproduce: 6 | 7 | Additional Information: -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Issue #, if available: 2 | 3 | Description of changes: 4 | 5 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea 3 | Automation/Testing/local.cfg 4 | .DS_Store -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the AWS Systems Manager repository 2 | Contributions to the repository should be made under the [Community folder](https://github.com/awslabs/amazon-ssm/tree/master/Community) via GitHub pull requests and discussed using GitHub issues. 3 | 4 | ## What can you contribute? 5 | Examples of contributions include (but not limited to): 6 | 7 | * Systems Manager Documents, licensed under the MIT No Attribution License, that (a) combine existing SSM features, or (b) run scripts or executables that demonstrate the management capabilities of the Systems Manager platform 8 | * Scripts and executables (a) that can be used in an SSM document, (b) provided to Amazon in source code form (rather than binary), (c) and licensed under the MIT No Attribution License 9 | * Cloud Formation Templates 10 | * Use cases and Documentation that extends SSM’s formal public documents by providing walkthroughs/cookbooks or documents use-cases of SSM 11 | 12 | Please add detailed descriptions, sample customer scenarios so that the content is usable. 13 | 14 | If you have any problems, please consult GitHub [issues](https://github.com/awslabs/amazon-ssm/issues) for this repository. If you do not find an existing problem, please file a new issue. 15 | 16 | ## Making the pull request 17 | Pull requests should be opened against the `master` branch. We recommend that you provide a readme or description with any script or executable you contribute so that it’s easy to understand and get started. 18 | 19 | ## Licensing 20 | All content must be clearly licensed to [MIT no attribution license](https://github.com/awslabs/amazon-ssm/blob/master/LICENSE). 21 | -------------------------------------------------------------------------------- /Community/101-SSH-PowerShell-Remoting/README.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | This PowerShell script was developed with the intention of deploying it to Windows Server systems, through the `AWS-RunRemoteScript` AWS Systems Manager document. When executed, this PowerShell script will perform the following actions: 4 | 5 | * Install PowerShell Core edition 6 | * Install the Win32 OpenSSH daemon for Microsoft Windows 7 | * Configure the Windows Firewall to allow inbound SSH connections 8 | * Configure OpenSSH to use PowerShell Core as the default shell 9 | 10 | -------------------------------------------------------------------------------- /Community/Compliance/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Community/Documents/Automation/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Community/Documents/Command/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Community/Inventory/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Community/Scripts/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Compliance/InSpec/PortCheck/Readme.md: -------------------------------------------------------------------------------- 1 | # Sample Inspec controls to do port check 2 | 3 | Controls listed here check RDP port on windows and SSH port on linux. Two checks are performed for each. 4 | 1. Whether the port is open or not 5 | 2. If the port is opened for all incoming addresses 6 | 7 | This repo can be used with AWS SSM documents. 8 | -------------------------------------------------------------------------------- /Compliance/InSpec/PortCheck/controls/linux_ssh_port_check.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | control 'Linux instance check' do 18 | title 'SSH access' 19 | desc 'SSH port should not be open to the world' 20 | impact 0.9 21 | require 'rbconfig' 22 | is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) 23 | if ! is_windows 24 | describe port(22) do 25 | it { should be_listening } 26 | its('addresses') {should_not include '0.0.0.0'} 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /Compliance/InSpec/PortCheck/controls/windows_rdp_port_check.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | control 'Windows instance check' do 18 | title 'RDP access' 19 | desc 'RDP port should not be open to the world' 20 | impact 0.9 21 | require 'rbconfig' 22 | is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) 23 | if is_windows 24 | describe port(3389) do 25 | it { should be_listening } 26 | its('addresses') {should_not include '0.0.0.0'} 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /Compliance/InSpec/PortCheck/inspec.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | name: inspec-test 18 | title: Simple cross platform tests for ports 19 | -------------------------------------------------------------------------------- /Compliance/InSpec/Readme.md: -------------------------------------------------------------------------------- 1 | All InSpec files 2 | -------------------------------------------------------------------------------- /Compliance/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyState/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Change Standby state of instances within an autoscaling group 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ### Steps 8 | 9 | 1. Create CloudFormation Template 10 | * CloudFormation template will create a lambda function that can change the standby state of an instance in an ASG 11 | 2. Execute lambda 12 | * Lambda function take parameters for ASG name, instance ID, and which state to put the instance into (either EitherStandby or ExitStandby) 13 | 3. Delete CloudFormation Template 14 | * Deleting the CF template will destroy any created IAM roles as well as the deployed Lambda 15 | 16 | ## Tests 17 | 18 | ### tests.py 19 | 20 | The tests for both Enter and Exit standby are defined in this file, with separate test functions for each action. 21 | 22 | ## Makefile 23 | 24 | This document requires the document to include some inline code for both CloudFormation Template and the SSM Document. 25 | The makefile is here to help facilitate this process. 26 | 27 | ### Building Document 28 | 29 | ``` 30 | make 31 | ``` 32 | 33 | 1. Parse CloudFormation Template 34 | 2. Embed lambda function located in Documents/Lambdas/change_asg_state.py into CloudFormation Template 35 | 3. Parse Documents/aws-ASGChangeStandbyState.json 36 | 4. Embed CloudFormation Template into Automation Document. 37 | 5. Output new Document into ./Output 38 | 39 | ### Cleaning Document 40 | 41 | ``` 42 | make clean 43 | ``` 44 | 45 | 1. Delete content of ./Output folder 46 | 47 | ### Test 48 | 49 | ``` 50 | make test 51 | ``` 52 | 53 | 1. Discover all test in this folder. 54 | 2. Execute all tests 55 | 56 | **Note**: You can also run individual test by telling python unit test framework which test to run, but make sure to run 57 | `make` before actually running any tests. 58 | 59 | ``` 60 | python -m unittest Tests.tests.TestCase.test_enter_standby_document 61 | python -m unittest Tests.tests.TestCase.test_exit_standby_document 62 | ``` -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyState/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "Systems Manager Automation - Change the Standby state of an EC2 instance in an autoscaling group", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) ID of EC2 Instance to change standby state for within ASG" 9 | }, 10 | "LambdaRoleArn": { 11 | "default": "", 12 | "type": "String", 13 | "description": "(Optional) The ARN of the role that allows Lambda created by Automation to perform the actions on your behalf. If not specified a transient role will be created to execute the Lambda function." 14 | }, 15 | "AutomationAssumeRole": { 16 | "default": "", 17 | "type": "String", 18 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf." 19 | } 20 | }, 21 | "mainSteps": [] 22 | } -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyState/Documents/aws-ASGChangeStandbyState.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "Change the Standby state of an EC2 instance in an autoscaling group", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) ID of EC2 Instance to change standby state for within ASG" 9 | }, 10 | "LambdaRoleArn": { 11 | "default": "", 12 | "type": "String", 13 | "description": "(Optional) The ARN of the role that allows Lambda created by Automation to perform the actions on your behalf. If not specified a transient role will be created to execute the Lambda function." 14 | }, 15 | "AutomationAssumeRole": { 16 | "default": "", 17 | "type": "String", 18 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf." 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "deployChangeStateLambda", 24 | "action": "aws:createStack", 25 | "maxAttempts": 1, 26 | "onFailure": "Abort", 27 | "inputs": { 28 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}", 29 | "TemplateBody": "{0}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "FunctionName", 33 | "ParameterValue": "asg-state-change-lambda-{{automation:EXECUTION_ID}}" 34 | }, 35 | { 36 | "ParameterKey": "LambdaRoleArn", 37 | "ParameterValue": "{{LambdaRoleArn}}" 38 | } 39 | ] 40 | } 41 | }, 42 | { 43 | "name": "changeState", 44 | "action": "aws:invokeLambdaFunction", 45 | "maxAttempts": 1, 46 | "onFailure": "Abort", 47 | "inputs": { 48 | "FunctionName": "asg-state-change-lambda-{{automation:EXECUTION_ID}}", 49 | "Payload": {} 50 | } 51 | }, 52 | { 53 | "name": "deleteChangeStateLambda", 54 | "action": "aws:deleteStack", 55 | "maxAttempts": 1, 56 | "onFailure": "Abort", 57 | "inputs": { 58 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}" 59 | } 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyState/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | TARGET_DIR = "./Output" 19 | 20 | documents: targetdir createdocuments 21 | @echo "Done making documents" 22 | 23 | targetdir: 24 | @echo "Making $(TARGET_DIR)" 25 | mkdir -p ./Output 26 | 27 | createdocuments: 28 | python ./Setup/create_document.py EnterStandby > ./Output/aws-ASGEnterStandby.json 29 | python ./Setup/create_document.py ExitStandby > ./Output/aws-ASGExitStandby.json 30 | 31 | test: documents 32 | python -m unittest discover Tests 33 | #python -m unittest Tests.tests.TestCase.test_enter_standby_document 34 | #python -m unittest Tests.tests.TestCase.test_exit_standby_document 35 | 36 | clean: 37 | @echo "Removing $(TARGET_DIR)" 38 | @rm -rf ./Output 39 | 40 | -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyState/Tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyStateWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Change Standby state of instances within an autoscaling group with approval 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ### Steps 8 | 9 | 1. Require approval for further execution 10 | * Once execution is approved, the next steps will occur 11 | 2. Create CloudFormation Template 12 | * CloudFormation template will create a lambda function that can change the standby state of an instance in an ASG 13 | 3. Execute lambda 14 | * Lambda function take parameters instance ID and the state to put the instance into (either EitherStandby or ExitStandby) 15 | 4. Delete CloudFormation Template 16 | * Deleting the CF template will destroy any created IAM roles as well as the deployed Lambda 17 | 18 | ## Tests 19 | 20 | ### tests.py 21 | 22 | The tests for both Enter and Exit standby are defined in this file, with separate test functions for each action. 23 | 24 | ### Building Document and Test 25 | 26 | 1. Change directory to /Automation/ASGChangeStandbyState/ 27 | 2. Run ```make``` 28 | 3. In the AWS console, navigate to the EC2 screen and select "Documents" under "SYSTEMS MANAGER SHARED RESOURCES" on the left-hand menu. 29 | 4. Click Create Document 30 | 5. Enter the name awstest-ASGEnterStandby 31 | 6. Select "Automation" as the document type 32 | 7. Copy and paste the contents of /Automation/ASGChangeStandbyState/Output/aws-ASGEnterStandby.json into the Content text area. 33 | 8. Click "Create Document" 34 | 9. Do the same for the exit standby document, substituting "awstest-ASGExitStandby" for the document name, and copy the contents of 35 | /Automation/ASGChangeStandbyState/Output/aws-ASGExitStandby.json into the document. 36 | 10. Change directory to /Automation/ASGChangeStandbyStateWithApproval/ and run ```python tests.py``` -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyStateWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Systems Manager Automation - Change the standby state of an EC2 instance in an auto-scaling group with approval", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "ID of the EC2 Instance to change standby state for within ASG" 9 | }, 10 | "LambdaRoleArn": { 11 | "default": "", 12 | "type": "String", 13 | "description": "The ARN of the role that allows Lambda created by Automation to perform the actions on your behalf" 14 | }, 15 | "StackName": { 16 | "default": "asg-state-change-lambda-cfn-stack", 17 | "type": "String", 18 | "description": "Name for the CloudFormation stack which creates the necessary lambda function to change ASG state" 19 | }, 20 | "LambdaFunctionName": { 21 | "default": "asg-state-change-lambda-function", 22 | "type": "String", 23 | "description": "Name for the lambda function which can change the ASG state" 24 | }, 25 | "AutomationAssumeRole": { 26 | "default": "", 27 | "type": "String", 28 | "description": "The ARN of the role that allows Automation to perform the actions on your behalf." 29 | } 30 | }, 31 | "mainSteps": [] 32 | } -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyStateWithApproval/Documents/aws-ASGEnterStandbyWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Systems Manager Automation - Put an EC2 instance in an auto-scaling group in Standby mode, with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "AutomationAssumeRole": { 7 | "type": "String", 8 | "description": "The ARN of the role that allows Automation to perform the actions on your behalf.", 9 | "default": "" 10 | }, 11 | "LambdaRoleArn": { 12 | "type": "String", 13 | "description": "The ARN of the role that allows Lambda created by Automation to perform the actions on your behalf", 14 | "default": "" 15 | }, 16 | "InstanceId": { 17 | "type": "String", 18 | "description": "ID of the EC2 Instance to change standby state for within ASG" 19 | }, 20 | "Approvers": { 21 | "type": "StringList", 22 | "description": "IAM user or user arn of approvers for the automation action" 23 | }, 24 | "SNSTopicArn": { 25 | "type": "String", 26 | "description": "The SNS topic ARN that you are using to get notifications on about EC2 retirement notifications. The SNS topic name must start with Automation." 27 | } 28 | }, 29 | "mainSteps": [ 30 | { 31 | "name": "approveStateChange", 32 | "action": "aws:approve", 33 | "maxAttempts": 1, 34 | "onFailure": "Abort", 35 | "inputs": { 36 | "NotificationArn": "{{SNSTopicArn}}", 37 | "Message": "Approval required to change ASG instance state", 38 | "MinRequiredApprovals": 1, 39 | "Approvers": "{{Approvers}}" 40 | } 41 | }, 42 | { 43 | "name":"changeASGInstanceStateAutomation", 44 | "action":"aws:executeAutomation", 45 | "maxAttempts":1, 46 | "timeoutSeconds":120, 47 | "onFailure":"Abort", 48 | "inputs":{ 49 | "DocumentName":"AWS-ASGEnterStandby", 50 | "RuntimeParameters":{ 51 | "AutomationAssumeRole": ["{{AutomationAssumeRole}}"], 52 | "LambdaRoleArn": ["{{LambdaRoleArn}}"], 53 | "InstanceId": ["{{InstanceId}}"] 54 | } 55 | } 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyStateWithApproval/Documents/aws-ASGExitStandbyWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Systems Manager Automation - Take an EC2 instance in an auto-scaling group out of Standby mode, with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "AutomationAssumeRole": { 7 | "type": "String", 8 | "description": "The ARN of the role that allows Automation to perform the actions on your behalf.", 9 | "default": "" 10 | }, 11 | "LambdaRoleArn": { 12 | "type": "String", 13 | "description": "The ARN of the role that allows Lambda created by Automation to perform the actions on your behalf", 14 | "default": "" 15 | }, 16 | "InstanceId": { 17 | "type": "String", 18 | "description": "ID of the EC2 Instance to change standby state for within ASG" 19 | }, 20 | "Approvers": { 21 | "type": "StringList", 22 | "description": "IAM user or user arn of approvers for the automation action" 23 | }, 24 | "SNSTopicArn": { 25 | "type": "String", 26 | "description": "The SNS topic ARN that you are using to get notifications on about EC2 retirement notifications. The SNS topic name must start with Automation." 27 | } 28 | }, 29 | "mainSteps": [ 30 | { 31 | "name": "approveStateChange", 32 | "action": "aws:approve", 33 | "maxAttempts": 1, 34 | "onFailure": "Abort", 35 | "inputs": { 36 | "NotificationArn": "{{SNSTopicArn}}", 37 | "Message": "Approval required to change ASG instance state", 38 | "MinRequiredApprovals": 1, 39 | "Approvers": "{{Approvers}}" 40 | } 41 | }, 42 | { 43 | "name":"changeASGInstanceStateAutomation", 44 | "action":"aws:executeAutomation", 45 | "maxAttempts":1, 46 | "timeoutSeconds":120, 47 | "onFailure":"Abort", 48 | "inputs":{ 49 | "DocumentName":"AWS-ASGExitStandby", 50 | "RuntimeParameters":{ 51 | "AutomationAssumeRole": ["{{AutomationAssumeRole}}"], 52 | "LambdaRoleArn": ["{{LambdaRoleArn}}"], 53 | "InstanceId": ["{{InstanceId}}"] 54 | } 55 | } 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /Documents/Automation/ASGChangeStandbyStateWithApproval/Tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-systems-manager/81deddae6d864f2e236346c880f88b7905ec549a/Documents/Automation/ASGChangeStandbyStateWithApproval/Tests/__init__.py -------------------------------------------------------------------------------- /Documents/Automation/AttachEBSVolumes/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Attach EBS Volume 2 | 3 | ## Notes 4 | 5 | Initial version will only support attaching an existing volume to an instance. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createStack - Execute CloudFormation Template to attach the volume. 13 | * Parameters: 14 | * Device: {{Device}} - The device name (for example, /dev/sdh or xvdh). 15 | * InstanceId: {{InstanceId}} - The ID of the instance. 16 | * VolumeId: {{VolumeId}} - The ID of the EBS volume. The volume and instance must be within the same Availability Zone. 17 | 2. aws:deleteStack - Delete CloudFormation Template. 18 | 19 | ## Test script 20 | 21 | Python script will: 22 | 1. Create a test stack with an instance and a volume 23 | 2. Execute automation document to attach volume to instance 24 | 3. Ensure the automation has executed successfully 25 | 4. Detach volume 26 | 5. Clean up test stack 27 | -------------------------------------------------------------------------------- /Documents/Automation/AttachEBSVolumes/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Attach EBS Volume", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "Device": { 7 | "type": "String", 8 | "description": "(Required) The device name (for example, /dev/sdh or xvdh )" 9 | }, 10 | "InstanceId": { 11 | "type": "String", 12 | "description": "(Required) The ID of the instance" 13 | }, 14 | "VolumeId": { 15 | "type": "String", 16 | "description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/AttachEBSVolumes/Documents/CloudFormationTemplates/CloudFormationAttachVolume.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Template to attach a EBS volume to an EC2 Instance 20 | Parameters: 21 | Device: 22 | Description: > 23 | The device name (for example, /dev/sdh or xvdh ) 24 | Type: String 25 | InstanceId: 26 | Description: > 27 | The ID of the instance 28 | Type: String 29 | VolumeId: 30 | Description: > 31 | The ID of the EBS volume. The volume and instance must be within the same Availability Zone 32 | Type: String 33 | Resources: 34 | TestResource: 35 | Type: AWS::EC2::VolumeAttachment 36 | DeletionPolicy: Retain 37 | Properties: 38 | Device: !Ref Device 39 | InstanceId: !Ref InstanceId 40 | VolumeId: !Ref VolumeId 41 | -------------------------------------------------------------------------------- /Documents/Automation/AttachEBSVolumes/Documents/aws-AttachEBSVolume.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Attach EBS Volume", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "Device": { 7 | "type": "String", 8 | "description": "(Required) The device name (for example, /dev/sdh or xvdh )" 9 | }, 10 | "InstanceId": { 11 | "type": "String", 12 | "description": "(Required) The ID of the instance" 13 | }, 14 | "VolumeId": { 15 | "type": "String", 16 | "description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "createDocumentStack", 27 | "action": "aws:createStack", 28 | "inputs": { 29 | "Capabilities": [ 30 | "CAPABILITY_IAM" 31 | ], 32 | "StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}", 33 | "Parameters": [ 34 | { 35 | "ParameterKey": "Device", 36 | "ParameterValue": "{{Device}}" 37 | }, 38 | { 39 | "ParameterKey": "InstanceId", 40 | "ParameterValue": "{{InstanceId}}" 41 | }, 42 | { 43 | "ParameterKey": "VolumeId", 44 | "ParameterValue": "{{VolumeId}}" 45 | } 46 | ], 47 | "TemplateBody": "..." 48 | } 49 | }, 50 | { 51 | "name": "deleteCloudFormationTemplate", 52 | "action": "aws:deleteStack", 53 | "inputs": { 54 | "StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}" 55 | } 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /Documents/Automation/AttachEBSVolumes/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-AttachEBSVolume.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/AttachIAMToInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Attach an IAM role to an Instance 2 | 3 | ## Notes 4 | 5 | To associate a role to an instance, we have to create an instance profile. 6 | By AWS Design, we can only have one role associated to an instance profile. 7 | So the new instance profile name will be the name of the role. 8 | Then we can associate the instance to an instance profile. 9 | 10 | There are two things to consider about attaching a role to an instance 11 | 1. Instance is already associated to a role 12 | 2. Instance is not associated to any role 13 | 14 | ## Document Design 15 | 16 | Refer to schema.json 17 | 18 | Document Steps: 19 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 20 | * Inputs: 21 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 22 | * Parameters: 23 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda 24 | * LambdaName: UpdateCFTemplate-{{automation:EXECUTION_ID}} 25 | 2. aws:invokeLambdaFunction - Execute Lambda to detach the volume 26 | * Inputs: 27 | * FunctionName: AttachIAMToInstanceLambda-{{automation:EXECUTION_ID}} - Lambda name to use 28 | * Payload: 29 | * Instance: {{Instance}} - The ID of the instance. 30 | * RoleName: {{RoleName}} - Role Name to associate the Instance 31 | 3. aws:deleteStack - Delete CloudFormation Template. 32 | * Inputs: 33 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 34 | 35 | ## Test script 36 | 37 | Instance is already associated to a role: 38 | 1. Create a test stack with an instance already associated to a role 39 | 2. Execute automation document to attach the role to an instance 40 | 3. Verify instance profile is replaced 41 | 4. Clean up test stack 42 | 43 | Instance is not associated to a role: 44 | 1. Create a test stack with an instance that is not associated to any role 45 | 2. Execute automation document to attach the role to an instance 46 | 3. Verify instance is associated to the role 47 | 4. Clean up test stack 48 | 49 | -------------------------------------------------------------------------------- /Documents/Automation/AttachIAMToInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Attach IAM to Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the instance." 9 | }, 10 | "RoleName": { 11 | "type": "String", 12 | "description": "(Required) Role Name to add" 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role assumed by lambda", 17 | "default": "" 18 | }, 19 | "AutomationAssumeRole": { 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 22 | "default": "" 23 | } 24 | }, 25 | "mainSteps": [], 26 | "outputs":[ 27 | "attachIAMToInstance.LogResult", 28 | "attachIAMToInstance.Payload" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /Documents/Automation/AttachIAMToInstance/Documents/aws-AttachIAMToInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Attach IAM to Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the instance." 9 | }, 10 | "RoleName": { 11 | "type": "String", 12 | "description": "(Required) Role Name to add" 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role assumed by lambda", 17 | "default": "" 18 | }, 19 | "AutomationAssumeRole": { 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 22 | "default": "" 23 | } 24 | }, 25 | "mainSteps": [ 26 | { 27 | "name": "createDocumentStack", 28 | "action": "aws:createStack", 29 | "inputs": { 30 | "Capabilities": [ 31 | "CAPABILITY_IAM" 32 | ], 33 | "StackName": "AttachIAMToInstanceStack{{automation:EXECUTION_ID}}", 34 | "Parameters": [ 35 | { 36 | "ParameterKey": "LambdaRoleArn", 37 | "ParameterValue": "{{LambdaAssumeRole}}" 38 | }, 39 | { 40 | "ParameterKey": "LambdaName", 41 | "ParameterValue": "AttachIAMToInstanceLambda-{{automation:EXECUTION_ID}}" 42 | } 43 | ], 44 | "TemplateBody": "..." 45 | } 46 | }, 47 | { 48 | "name": "attachIAMToInstance", 49 | "action": "aws:invokeLambdaFunction", 50 | "inputs": { 51 | "FunctionName": "AttachIAMToInstanceLambda-{{automation:EXECUTION_ID}}", 52 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"RoleName\": \"{{RoleName}}\"}", 53 | "LogType": "Tail" 54 | } 55 | }, 56 | { 57 | "name": "deleteCloudFormationTemplate", 58 | "action": "aws:deleteStack", 59 | "inputs": { 60 | "StackName": "AttachIAMToInstanceStack{{automation:EXECUTION_ID}}" 61 | } 62 | } 63 | ], 64 | "outputs":[ 65 | "attachIAMToInstance.LogResult", 66 | "attachIAMToInstance.Payload" 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /Documents/Automation/AttachIAMToInstance/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-AttachIAMToInstance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/ConfigureCloudWatchOnEC2Instance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Configure CloudWatch on EC2 Instance 2 | 3 | Establishes CloudWatch monitoring on an EC2 Instance 4 | 5 | ## Inputs 6 | 7 | #### InstanceId 8 | * The instance for which CloudWatch monitoring will be established. 9 | * Type: String 10 | * Required: True 11 | 12 | #### status 13 | * Specifies whether to enable or disable CloudWatch. Valid values: "Enabled" | "Disabled", defaults to "Enabled" 14 | * Type: String 15 | * Required: False 16 | 17 | #### properties 18 | * The configuration for CloudWatch in JSON format. See http://docs.aws.amazon.com/ssm/latest/APIReference/aws-cloudWatch.html 19 | * Type: String 20 | * Required: False 21 | 22 | ## Outputs 23 | The automation execution has no outputs. 24 | -------------------------------------------------------------------------------- /Documents/Automation/ConfigureCloudWatchOnEC2Instance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Configure CloudWatch on EC2 Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) InstanceId of the EC2 instance to configure" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "status" : { 16 | "type": "String", 17 | "description": "(Optional) Specifies whether to enable or disable CloudWatch. Valid values: \"Enabled\" | \"Disabled\"", 18 | "allowedValues": [ 19 | "Enabled", 20 | "Disabled" 21 | ], 22 | "default": "Enabled" 23 | }, 24 | "properties": { 25 | "type": "String", 26 | "description": "(Optional) The configuration for CloudWatch in JSON format." 27 | } 28 | }, 29 | "mainSteps": [] 30 | } 31 | -------------------------------------------------------------------------------- /Documents/Automation/ConfigureCloudWatchOnEC2Instance/Documents/Lambdas/configure_cloudwatch_on_ec2_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | ec2_client = boto3.client('ec2') 22 | instance_id = event["InstanceId"] 23 | new_state = event["status"] or "Enabled" 24 | 25 | if new_state == "Enabled": 26 | ec2_client.monitor_instances(InstanceIds=[instance_id]) 27 | if new_state == "Disabled": 28 | ec2_client.unmonitor_instances(InstanceIds=[instance_id]) 29 | -------------------------------------------------------------------------------- /Documents/Automation/ConfigureCloudWatchOnEC2Instance/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-ConfigureCloudWatchOnEC2Instance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/ConfigureCloudWatchOnEC2Instance/README.md: -------------------------------------------------------------------------------- 1 | # Configure CloudWatch on EC2 Instance 2 | 3 | Establishes CloudWatch monitoring on an EC2 Instance 4 | 5 | ## Inputs 6 | 7 | #### InstanceId 8 | * The EC2 instance for which CloudWatch monitoring will be established. 9 | * Type: String 10 | * Required: True 11 | 12 | #### status 13 | * Specifies whether to Enable or disable CloudWatch. Valid values: "Enabled" | "Disabled", defaults to "Enabled" 14 | * Type: String 15 | * Required: False 16 | 17 | #### properties 18 | * The configuration for CloudWatch in JSON format. See http://docs.aws.amazon.com/ssm/latest/APIReference/aws-cloudWatch.html 19 | * Type: String 20 | * Required: False 21 | 22 | ## Outputs 23 | The automation execution has no outputs. 24 | -------------------------------------------------------------------------------- /Documents/Automation/CopySnapshot/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Copy Snapshot 2 | 3 | ## Notes 4 | 5 | This will copy a snapshot 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 13 | * Inputs: 14 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 15 | * Parameters: 16 | * LambdaRole: {{LambdaAssumeRole}} - The ARN of the role assumed by lambda. 17 | * LambdaName: CopySnapshotLambda-{{automation:EXECUTION_ID}} 18 | 2. aws:invokeLambdaFunction - Execute Lambda to detach the volume 19 | * Inputs: 20 | * FunctionName: CopySnapshotLambda-{{automation:EXECUTION_ID}} - Lambda name to use 21 | * Payload: 22 | * SnapshotId: {{SnapshotId}} - The ID of the EBS snapshot to copy. 23 | * Region: {{Region}} - The ID of the EBS snapshot to copy. 24 | * Description: {{Description}} - A description for the EBS snapshot. 25 | 3. aws:deleteStack - Delete CloudFormation Template. 26 | * Inputs: 27 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 28 | 29 | ## Test script 30 | 31 | Python script will: 32 | 1. Create a test stack with the assumed role and volume 33 | 2. Create a snapshot 34 | 3. Execute automation document to copy the snapshot 35 | 4. Verify that the snapshot exists 36 | 5. Clean up delete the snapshot, (if exists) 37 | 6. Clean up test stack -------------------------------------------------------------------------------- /Documents/Automation/CopySnapshot/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Copy Snapshot", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "SnapshotId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the EBS snapshot to copy." 9 | }, 10 | "SourceRegion": { 11 | "type": "String", 12 | "description": "(Required) The ID of the region that contains the snapshot to be copied." 13 | }, 14 | "Description": { 15 | "type": "String", 16 | "description": "(Optional) A description for the EBS snapshot.", 17 | "default": "" 18 | }, 19 | "LambdaAssumeRole": { 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role assumed by lambda", 22 | "default": "" 23 | }, 24 | "AutomationAssumeRole": { 25 | "default": "", 26 | "type": "String", 27 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf." 28 | } 29 | }, 30 | "mainSteps": [], 31 | "outputs": [ 32 | "copySnapshot.Payload" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /Documents/Automation/CopySnapshot/Documents/Lambdas/copy_snapshot.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | ec2_client = boto3.client("ec2") 22 | 23 | snapshot_id = event["SnapshotId"] 24 | source_region = event["SourceRegion"] 25 | description = event["Description"] 26 | response = ec2_client.copy_snapshot( 27 | Description=description, 28 | SourceRegion=source_region, 29 | SourceSnapshotId=snapshot_id 30 | ) 31 | 32 | return { 33 | "SnapshotId": response["SnapshotId"] 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Documents/Automation/CopySnapshot/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-CopySnapshot.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/CreateImage/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Create an Amazon Machine Image (AMI) 2 | 3 | ## Notes 4 | 5 | Create an Amazon Machine Image (AMI) from an Amazon EC2 instance 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createImage - Creates a new AMI from an Amazon EC2 instance 13 | * Inputs: 14 | * InstanceId: {{InstanceId}} - The ID of the Amazon EC2 instance. 15 | 16 | ## Test script 17 | 18 | Python script will: 19 | 1. Create a test stack with the automation assumed role and Amazon EC2 instance 20 | 2. Execute automation document create an Amazon Machine Image (AMI) of the Amazon EC2 instance 21 | 3. Verify that the Amazon Machine Image is created 22 | 4. Deregister the Amazon Machine Image and delete associated Snapshot. 23 | 5. Clean up test stack 24 | -------------------------------------------------------------------------------- /Documents/Automation/CreateImage/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Creates a new Amazon Machine Image (AMI) from an Amazon EC2 instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the Amazon EC2 instance." 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/CreateImage/Documents/aws-CreateImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Creates a new Amazon Machine Image (AMI) from an Amazon EC2 instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the Amazon EC2 instance." 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "createImage", 19 | "action": "aws:createImage", 20 | "maxAttempts": 3, 21 | "onFailure": "Abort", 22 | "inputs": { 23 | "InstanceId": "{{ InstanceId }}", 24 | "ImageName": "{{ InstanceId }}_{{automation:EXECUTION_ID}}", 25 | "NoReboot": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /Documents/Automation/CreateImage/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-CreateImage.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/CreateSnapshot/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Create Snapshot 2 | 3 | ## Notes 4 | 5 | This will create a snapshot 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 13 | * Inputs: 14 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 15 | * Parameters: 16 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to create the snapshot. 17 | * LambdaName: CreateSnapshotLambda-{{automation:EXECUTION_ID}} 18 | 2. aws:invokeLambdaFunction - Execute Lambda to detach the volume 19 | * Inputs: 20 | * FunctionName: CreateSnapshotLambda-{{automation:EXECUTION_ID}} - Lambda name to use 21 | * Payload: 22 | * VolumeId: {{VolumeId}} - The ID of the EBS volume. 23 | * Description: {{Description}} - A description for the EBS snapshot. 24 | 3. aws:deleteStack - Delete CloudFormation Template. 25 | * Inputs: 26 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 27 | 28 | ## Test script 29 | 30 | Python script will: 31 | 1. Create a test stack with the automation assumed role and volume 32 | 2. Execute automation document create a snapshot of that volume 33 | 4. Verify that the snapshot is created 34 | 5. Delete the snapshot 35 | 6. Clean up test stack 36 | -------------------------------------------------------------------------------- /Documents/Automation/CreateSnapshot/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Create Snapshot", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "VolumeId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the volume." 9 | }, 10 | "Description": { 11 | "type": "String", 12 | "description": "(Optional) A description for the snapshot", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | }, 20 | "AutomationAssumeRole": { 21 | "type": "String", 22 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 23 | "default": "" 24 | } 25 | }, 26 | "mainSteps": [] 27 | } 28 | -------------------------------------------------------------------------------- /Documents/Automation/CreateSnapshot/Documents/Lambdas/create_snapshot.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | ec2 = boto3.resource('ec2') 22 | 23 | volume_id = event["VolumeId"] 24 | description = event["Description"] 25 | volume = ec2.Volume(volume_id) 26 | volume.create_snapshot(Description=description) 27 | 28 | -------------------------------------------------------------------------------- /Documents/Automation/CreateSnapshot/Documents/aws-CreateSnapshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Create Snapshot", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "VolumeId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the volume." 9 | }, 10 | "Description": { 11 | "type": "String", 12 | "description": "(Optional) A description for the snapshot", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | }, 20 | "AutomationAssumeRole": { 21 | "type": "String", 22 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 23 | "default": "" 24 | } 25 | }, 26 | "mainSteps": [ 27 | { 28 | "name": "createDocumentStack", 29 | "action": "aws:createStack", 30 | "inputs": { 31 | "Capabilities": [ 32 | "CAPABILITY_IAM" 33 | ], 34 | "StackName": "CreateSnapshotStack{{automation:EXECUTION_ID}}", 35 | "Parameters": [ 36 | { 37 | "ParameterKey": "LambdaRoleArn", 38 | "ParameterValue": "{{LambdaAssumeRole}}" 39 | }, 40 | { 41 | "ParameterKey": "LambdaName", 42 | "ParameterValue": "CreateSnapshotLambda-{{automation:EXECUTION_ID}}" 43 | } 44 | ], 45 | "TemplateBody": "..." 46 | } 47 | }, 48 | { 49 | "name": "createSnapshot", 50 | "action": "aws:invokeLambdaFunction", 51 | "inputs": { 52 | "FunctionName": "CreateSnapshotLambda-{{automation:EXECUTION_ID}}", 53 | "Payload": "{\"VolumeId\": \"{{VolumeId}}\", \"Description\": \"{{Description}}\"}" 54 | } 55 | }, 56 | { 57 | "name": "deleteCloudFormationTemplate", 58 | "action": "aws:deleteStack", 59 | "inputs": { 60 | "StackName": "CreateSnapshotStack{{automation:EXECUTION_ID}}" 61 | } 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /Documents/Automation/CreateSnapshot/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-CreateSnapshot.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormation/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Delete CloudFormation stacks based on their name/ID 2 | 3 | ## Notes 4 | 5 | The IAM role used for the AutomationAssumeRole parameter must have the following permissions assigned (see 6 | http://docs.aws.amazon.com/systems-manager/latest/userguide/automation-actions.html#automation-action-deletestack): 7 | 8 | ```json 9 | { 10 | "Version":"2012-10-17", 11 | "Statement":[ 12 | { 13 | "Effect":"Allow", 14 | "Action":[ 15 | "sqs:*", 16 | "cloudformation:DeleteStack", 17 | "cloudformation:DescribeStacks" 18 | ], 19 | "Resource":"*" 20 | } 21 | ] 22 | } 23 | ``` 24 | 25 | ## Document Design 26 | 27 | Refer to schema.json 28 | 29 | Document Steps: 30 | 1. aws:deleteStack 31 | * Inputs: 32 | * StackName: {{StackNameOrId}} - Stack name or unique ID 33 | 34 | ## Test script 35 | 36 | Python script will: 37 | 1. Create CloudFormation stack from template 38 | 2. Ensure stack is running 39 | 3. Execute the automation document which will tear down and delete the stack 40 | 4. Ensure the automation has executed successfully 41 | 5. Query the CloudFormation API to ensure the stack has been successfully deleted 42 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormation/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete CloudFormation Stack", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be deleted" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormation/Documents/aws-DeleteCloudFormation.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete CloudFormation Stack", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be deleted" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "deleteCloudFormationStack", 19 | "action":"aws:deleteStack", 20 | "maxAttempts":1, 21 | "onFailure":"Abort", 22 | "inputs":{ 23 | "StackName":"{{StackNameOrId}}" 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormation/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - DeleteCloudFormationStack 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | Parameters: 30 | AMI: 31 | Description: AMI ID for instances. 32 | Type: String 33 | INSTANCETYPE: 34 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 35 | Type: String 36 | Resources: 37 | Instance0: 38 | Type: AWS::EC2::Instance 39 | Properties: 40 | ImageId: 41 | Ref: AMI 42 | InstanceType: 43 | Ref: INSTANCETYPE 44 | Instance1: 45 | Type: AWS::EC2::Instance 46 | Properties: 47 | ImageId: 48 | Ref: AMI 49 | InstanceType: 50 | Ref: INSTANCETYPE 51 | 52 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormationWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Delete CloudFormation stacks based on their name/ID with approval 2 | 3 | ## Notes 4 | 5 | The IAM role used for the AutomationAssumeRole parameter must have the following permissions assigned (see 6 | http://docs.aws.amazon.com/systems-manager/latest/userguide/automation-actions.html#automation-action-deletestack): 7 | 8 | ```json 9 | { 10 | "Version":"2012-10-17", 11 | "Statement":[ 12 | { 13 | "Effect":"Allow", 14 | "Action":[ 15 | "sqs:*", 16 | "cloudformation:DeleteStack", 17 | "cloudformation:DescribeStacks" 18 | ], 19 | "Resource":"*" 20 | } 21 | ] 22 | } 23 | ``` 24 | 25 | ## Document Design 26 | 27 | Refer to schema.json 28 | 29 | Document Steps: 30 | 1. aws:approve 31 | * Inputs: 32 | * NotificationArn: {{SNSTopicArn}} 33 | * Message: "Please approve stopping the selected instance(s)" 34 | * MinRequiredApprovals: 1 35 | * Approvers: {{Approvers}} 36 | 2. aws:deleteStack 37 | * Inputs: 38 | * StackName: {{StackName}} - Stack name or unique ID 39 | 40 | ## Test script 41 | 42 | Python script will: 43 | 1. Create CloudFormation stack from template 44 | 2. Ensure stack is running 45 | 3. Execute the automation document which will wait for user approval before continuing 46 | 4. Use ssm_client.send_automation_signal with SignalType 'Approve' to automatically approve the execution 47 | 5. Ensure the automation has executed successfully 48 | 6. Query the CloudFormation API to ensure the stack has been successfully deleted 49 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormationWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete CloudFormation Stack with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be deleted" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for delete CloudFormation Stack. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteCloudFormationWithApproval/Documents/aws-DeleteCloudFormationWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete CloudFormation Stack with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be deleted" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for delete CloudFormation Stack. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "approve", 27 | "action": "aws:approve", 28 | "onFailure": "Abort", 29 | "inputs": { 30 | "NotificationArn": "{{ SNSTopicArn }}", 31 | "Message": "Approval required to delete CloudFormation stack: {{StackNameOrId}}", 32 | "MinRequiredApprovals": 1, 33 | "Approvers": "{{ Approvers }}" 34 | } 35 | }, 36 | { 37 | "name": "deleteCloudFormationStack", 38 | "action":"aws:deleteStack", 39 | "maxAttempts":1, 40 | "onFailure":"Abort", 41 | "inputs":{ 42 | "StackName":"{{StackNameOrId}}" 43 | } 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteImage/Design/Design.md: -------------------------------------------------------------------------------- 1 | # "Delete Amazon Machine Image (AMI) and all associated snapshots." 2 | 3 | ## Notes 4 | 5 | Deletes the specified Amazon Machine Image (AMI) and all related snapshots. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:deleteImage - Deletes the Amazon Machine Image (AMI) and all related snapshots. 13 | * Inputs: 14 | * ImageId: {{ImageId}} - The ID of the Amazon Machine Image (AMI). 15 | 16 | 17 | ## Test script 18 | 19 | Python script will: 20 | 1. Create a test stack with the automation assumed role and Amazon EC2 Instance. 21 | 2. Create an Amazon Machine Image (AMI) from the Amazon EC2 Instance. 22 | 3. Execute automation document to delete the specified Amazon Machine Image (AMI) and associated Snapshot. 23 | 3. Deregister the Amazon Machine Image (AMI) and delete associated Snapshot 24 | 4. Verify that the Amazon Machine Image (AMI) and associated Snapshot has been deleted 25 | 5. Clean up test stack 26 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteImage/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete Amazon Machine Image (AMI) and all associated snapshots.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "ImageId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the Amazon Machine Image (AMI)." 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } -------------------------------------------------------------------------------- /Documents/Automation/DeleteImage/Documents/aws-DeleteImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete Amazon Machine Image (AMI) and all associated snapshots.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "ImageId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the Amazon Machine Image (AMI)." 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "deleteImage", 19 | "action": "aws:deleteImage", 20 | "maxAttempts": 3, 21 | "onFailure": "Abort", 22 | "inputs": { 23 | "ImageId": "{{ ImageId }}" 24 | } 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /Documents/Automation/DeleteImage/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | #createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-DeleteImage.json 28 | 29 | test: 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteSnapshot/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Delete Snapshot 2 | 3 | ## Notes 4 | 5 | This will delete a snapshot 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 13 | * Inputs: 14 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 15 | * Parameters: 16 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to delete the snapshot. 17 | * LambdaName: DeleteSnapshotLambda-{{automation:EXECUTION_ID}} 18 | 2. aws:invokeLambdaFunction - Execute Lambda to detach the volume 19 | * Inputs: 20 | * FunctionName: DeleteSnapshotLambda-{{automation:EXECUTION_ID}} - Lambda name to use 21 | * Payload: 22 | * SnapshotId: {{SnapshotId}} - The ID of the EBS volume. The volume and instance must be within the same Availability Zone. 23 | 3. aws:deleteStack - Delete CloudFormation Template. 24 | * Inputs: 25 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 26 | 27 | ## Test script 28 | 29 | Python script will: 30 | 1. Create a test stack with a volume 31 | 2. Create a snapshot 32 | 3. Execute automation document to delete a snapshot 33 | 4. Verify that the snapshot does not exist 34 | 5. Clean up delete the snapshot, (if exists) 35 | 6. Clean up test stack 36 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteSnapshot/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete Snapshot", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "SnapshotId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the EBS snapshot." 9 | }, 10 | "LambdaAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role assumed by lambda", 13 | "default": "" 14 | }, 15 | "AutomationAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [] 22 | } 23 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteSnapshot/Documents/Lambdas/delete_snapshot.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | ec2_client = boto3.client('ec2') 22 | 23 | snapshot_id = event["SnapshotId"] 24 | ec2_client.delete_snapshot( 25 | SnapshotId=snapshot_id 26 | ) 27 | 28 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteSnapshot/Documents/aws-DeleteSnapshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete Snapshot", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "SnapshotId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the EBS snapshot." 9 | }, 10 | "LambdaAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role assumed by lambda", 13 | "default": "" 14 | }, 15 | "AutomationAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "createDocumentStack", 24 | "action": "aws:createStack", 25 | "inputs": { 26 | "Capabilities": [ 27 | "CAPABILITY_IAM" 28 | ], 29 | "StackName": "DeleteSnapshotStack{{automation:EXECUTION_ID}}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "LambdaRoleArn", 33 | "ParameterValue": "{{LambdaAssumeRole}}" 34 | }, 35 | { 36 | "ParameterKey": "LambdaName", 37 | "ParameterValue": "DeleteSnapshotLambda-{{automation:EXECUTION_ID}}" 38 | } 39 | ], 40 | "TemplateBody": "..." 41 | } 42 | }, 43 | { 44 | "name": "deleteSnapshot", 45 | "action": "aws:invokeLambdaFunction", 46 | "inputs": { 47 | "FunctionName": "DeleteSnapshotLambda-{{automation:EXECUTION_ID}}", 48 | "Payload": "{\"SnapshotId\": \"{{SnapshotId}}\"}" 49 | } 50 | }, 51 | { 52 | "name": "deleteCloudFormationTemplate", 53 | "action": "aws:deleteStack", 54 | "inputs": { 55 | "StackName": "DeleteSnapshotStack{{automation:EXECUTION_ID}}" 56 | } 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /Documents/Automation/DeleteSnapshot/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-DeleteSnapshot.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/DetachEBSVolumes/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Detach EBS Volume 2 | 3 | ## Notes 4 | 5 | Initial version will only support detaching an unmounted volume from an instance. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 13 | * Inputs: 14 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 15 | * Parameters: 16 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to detach the volume from the instance 17 | * LambdaName: UpdateCFTemplate-{{automation:EXECUTION_ID}} 18 | 2. aws:invokeLambdaFunction - Execute Lambda to detach the volume 19 | * Inputs: 20 | * FunctionName: UpdateCFTemplate-{{automation:EXECUTION_ID}} - Lambda name to use 21 | * Payload: 22 | * VolumeId: {{VolumeId}} - The ID of the EBS volume. The volume and instance must be within the same Availability Zone. 23 | 3. aws:deleteStack - Delete CloudFormation Template. 24 | * Inputs: 25 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 26 | 27 | ## Test script 28 | 29 | Basic Test will: 30 | 1. Create a test stack with an instance and a volume 31 | 2. Execute automation document to detach the volume from the instance 32 | 3. Ensure the automation has executed successfully 33 | 4. Clean up test stack 34 | 35 | Mounted Test Test will: 36 | 1. Create a test stack with an instance and a volume 37 | 2. Mount the volume on the instance 38 | 2. Execute automation document to detach the volume from the instance 39 | 3. Ensure the automation has executed failed 40 | 4. Clean up test stack 41 | -------------------------------------------------------------------------------- /Documents/Automation/DetachEBSVolumes/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Detach EBS Volume", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "VolumeId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" 9 | }, 10 | "LambdaAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role assumed by lambda", 13 | "default": "" 14 | }, 15 | "AutomationAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [] 22 | } 23 | -------------------------------------------------------------------------------- /Documents/Automation/DetachEBSVolumes/Documents/aws-DetachEBSVolume.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Detach EBS Volume", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "VolumeId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" 9 | }, 10 | "LambdaAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role assumed by lambda", 13 | "default": "" 14 | }, 15 | "AutomationAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "createDocumentStack", 24 | "action": "aws:createStack", 25 | "inputs": { 26 | "Capabilities": [ 27 | "CAPABILITY_IAM" 28 | ], 29 | "StackName": "DetachEBSVolumeStack{{automation:EXECUTION_ID}}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "LambdaRoleArn", 33 | "ParameterValue": "{{LambdaAssumeRole}}" 34 | }, 35 | { 36 | "ParameterKey": "LambdaName", 37 | "ParameterValue": "DetachVolumeLambda-{{automation:EXECUTION_ID}}" 38 | } 39 | ], 40 | "TemplateBody": "..." 41 | } 42 | }, 43 | { 44 | "name": "detachVolume", 45 | "action": "aws:invokeLambdaFunction", 46 | "inputs": { 47 | "FunctionName": "DetachVolumeLambda-{{automation:EXECUTION_ID}}", 48 | "Payload": "{\"VolumeId\": \"{{VolumeId}}\"}", 49 | "LogType": "Tail" 50 | } 51 | }, 52 | { 53 | "name": "deleteCloudFormationTemplate", 54 | "action": "aws:deleteStack", 55 | "inputs": { 56 | "StackName": "DetachEBSVolumeStack{{automation:EXECUTION_ID}}" 57 | } 58 | } 59 | ], 60 | "outputs":[ 61 | "detachVolume.LogResult" 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /Documents/Automation/DetachEBSVolumes/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-DetachEBSVolume.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/EncryptRootVolume/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Encrypt EBS root volume 2 | 3 | ## Notes 4 | 5 | Encrypts the root volume of an EC2 instance. This will be a replace operation and not an in-line encryption operation. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:npark-encryptrootvolume - Execute CloudFormation Template to attach the volume. 13 | * Parameters: 14 | * instanceId: (Required) Instance ID of the ec2 instance whose root volume needs to be encrypted 15 | * region: (Required) Region in which the ec2 instance belong 16 | * KmsKeyId: (Required) Customer KMS key to use during the encryption 17 | * devicename: (Optional) Device name of the root volume. Defaults to /dev/sda1 18 | * AutomationAssumeRole: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf 19 | 20 | ## Test script 21 | 22 | Python script will: 23 | # 1. Create a test stack with an instance, a volume and a KMS Key (Customer managed) 24 | # 2. Execute automation document to replace the root volume with the encrypted one (after a copy operation of the root volume snapshot) 25 | # 3. Ensure the Automation has executed successfull 26 | # 4. Clean up test stack 27 | -------------------------------------------------------------------------------- /Documents/Automation/EncryptRootVolume/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "Encrypt Root Volume", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "instanceId": { 7 | "description": "Instance ID of the ec2 instance whose root volume needs to be encrypted", 8 | "type": "String" 9 | }, 10 | "region": { 11 | "description": "Region in which the ec2 instance belong", 12 | "type": "String" 13 | }, 14 | "KmsKeyId": { 15 | "description": "Customer KMS key to use during the encryption", 16 | "type": "String" 17 | }, 18 | "devicename": { 19 | "description": "Device name of the root volume. Defaults to /dev/sda1", 20 | "type": "String" 21 | }, 22 | "AutomationAssumeRole": { 23 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf", 24 | "type": "String" 25 | } 26 | }, 27 | "mainSteps": [] 28 | } 29 | -------------------------------------------------------------------------------- /Documents/Automation/EncryptRootVolume/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/npark-EncryptRootVolume.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "Creates a Linux Managed Instance", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "AmiId": { 7 | "type": "String", 8 | "description": "(Required) AMI id to use for launching the instance.", 9 | "default": "window|linux" 10 | }, 11 | "VpcId": { 12 | "type": "String", 13 | "description": "(Required) New instance will be deployed into this vpc or in the default vpc if not specified.", 14 | "default": "Default" 15 | }, 16 | "SubnetId": { 17 | "type": "String", 18 | "description": "(Required) New instance will be deployed into this subnet or in the default subnet if not specified.", 19 | "default": "Default" 20 | }, 21 | "RoleName": { 22 | "type": "String", 23 | "description": "(Required) Role Name to create.", 24 | "default": "SSMManagedInstanceProfileRole" 25 | }, 26 | "GroupName": { 27 | "type": "String", 28 | "description": "(Required) Security Group Name to create.", 29 | "default": "SSMSecurityGroupFor{Windows|Linux}Instances" 30 | }, 31 | "InstanceType": { 32 | "type": "String", 33 | "description": "(Required) Type of instance to launch. Default is t2.medium.", 34 | "default": "t2.medium" 35 | }, 36 | "KeyPairName": { 37 | "type": "String", 38 | "description": "(Required) Key pair to use when creating instance." 39 | }, 40 | "RemoteAccessCidr": { 41 | "type": "String", 42 | "description": "(Optional) Specify CIDR allowed to access the instance remotely through SSH/RDP. No rule will be added if left blank", 43 | "default": "" 44 | }, 45 | "AutomationAssumeRole": { 46 | "type": "String", 47 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf", 48 | "default": "" 49 | }, 50 | "StackName": { 51 | "type": "String", 52 | "description": "(Optional) Specify stack name used by this document", 53 | "default": "CreateManagedInstanceStack{{automation:EXECUTION_ID}}" 54 | } 55 | }, 56 | "mainSteps": [] 57 | } -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Documents/Lambdas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-systems-manager/81deddae6d864f2e236346c880f88b7905ec549a/Documents/Automation/ManagedInstance/Documents/Lambdas/__init__.py -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Documents/Lambdas/subnet_info.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import traceback 3 | 4 | import cfnresponse 5 | 6 | 7 | def handler_subnet_info(event, context): 8 | try: 9 | ec2 = boto3.client('ec2') 10 | vpc_id = event["ResourceProperties"].get("VpcId", "") 11 | subnet_id = event["ResourceProperties"].get("SubnetId", "") 12 | 13 | data = {} 14 | 15 | if len(subnet_id) == 0 or subnet_id == "Default": 16 | subnet_id = "" 17 | for subnet in ec2.describe_subnets(Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}]).get('Subnets'): 18 | if subnet.get('DefaultForAz', False) and subnet['VpcId'] == vpc_id: 19 | subnet_id = subnet['SubnetId'] 20 | break 21 | if len(subnet_id) == 0: 22 | raise Exception("Unable to find default subnet for vpc") 23 | data["SubnetId"] = subnet_id 24 | 25 | cfnresponse.send(event, context, cfnresponse.SUCCESS, data, event.get("PhysicalResourceId", None)) 26 | except Exception as e: 27 | print str(e) 28 | traceback.print_exc() 29 | cfnresponse.send(event, context, cfnresponse.FAILED, {}, event.get("PhysicalResourceId", None)) 30 | 31 | 32 | def handler_delete(event, context): 33 | # Nothing to do... this is a informational lambda and no resource is created. 34 | cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, event["PhysicalResourceId"]) 35 | 36 | 37 | def handler(event, context): 38 | if event["RequestType"] in ["Create", "Update"]: 39 | handler_subnet_info(event, context) 40 | elif event["RequestType"] in ["Delete"]: 41 | handler_delete(event, context) 42 | -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Documents/aws-CreateManagedInstanceWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "parameters": { 3 | "Approvers": { 4 | "type": "StringList", 5 | "description": "(Required) IAM user or user arn of approvers for the automation action" 6 | }, 7 | "SNSTopicArn": { 8 | "type": "String", 9 | "description": "(Required) The SNS topic ARN used to send pending approval notification for creating a new managed instance. The SNS topic name must start with Automation." 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Documents/aws-CreateManagedLinuxInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Creates a Linux Managed Instance", 3 | "parameters": { 4 | "AmiId": { 5 | }, 6 | "RemoteAccessCidr": { 7 | "description": "(Required) Creates Security group with port for SSH(Port range 22) open to IPs specified by CIDR (default is 0.0.0.0/0). If the security group already exists it will not be modified and rules will not be changed." 8 | }, 9 | "GroupName": { 10 | "default": "SSMSecurityGroupForLinuxInstances" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Documents/aws-CreateManagedWindowsInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Creates a Windows Managed Instance", 3 | "parameters": { 4 | "AmiId": { 5 | "default": "{{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}" 6 | }, 7 | "RemoteAccessCidr": { 8 | "description": "(Required) Creates Security group with port for RDP (Port range 3389) open to IPs specified by CIDR (default is 0.0.0.0/0). If the security group already exists it will not be modified and rules will not be changed." 9 | }, 10 | "GroupName": { 11 | "default": "SSMSecurityGroupForLinuxInstances" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-systems-manager/81deddae6d864f2e236346c880f88b7905ec549a/Documents/Automation/ManagedInstance/Tests/__init__.py -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Tests/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-systems-manager/81deddae6d864f2e236346c880f88b7905ec549a/Documents/Automation/ManagedInstance/Tests/lib/__init__.py -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/Tests/lib/cfnresponse.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. 2 | # This file is licensed to you under the AWS Customer Agreement (the "License"). 3 | # You may not use this file except in compliance with the License. 4 | # A copy of the License is located at http://aws.amazon.com/agreement/ . 5 | # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. 6 | # See the License for the specific language governing permissions and limitations under the License. 7 | 8 | from botocore.vendored import requests 9 | import json 10 | 11 | SUCCESS = "SUCCESS" 12 | FAILED = "FAILED" 13 | 14 | def send(event, context, responseStatus, responseData, physicalResourceId): 15 | responseUrl = event['ResponseURL'] 16 | 17 | print responseUrl 18 | 19 | responseBody = {} 20 | responseBody['Status'] = responseStatus 21 | responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name 22 | responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name 23 | responseBody['StackId'] = event['StackId'] 24 | responseBody['RequestId'] = event['RequestId'] 25 | responseBody['LogicalResourceId'] = event['LogicalResourceId'] 26 | responseBody['Data'] = responseData 27 | 28 | json_responseBody = json.dumps(responseBody) 29 | 30 | print "Response body:\n" + json_responseBody 31 | 32 | headers = { 33 | 'content-type' : '', 34 | 'content-length' : str(len(json_responseBody)) 35 | } 36 | 37 | try: 38 | response = requests.put(responseUrl, 39 | data=json_responseBody, 40 | headers=headers) 41 | print "Status code: " + response.reason 42 | except Exception as e: 43 | print "send(..) failed executing requests.put(..): " + str(e) 44 | -------------------------------------------------------------------------------- /Documents/Automation/ManagedInstance/makefile: -------------------------------------------------------------------------------- 1 | 2 | TARGET_DIR = "./Output" 3 | 4 | documents: targetdir createdocuments 5 | @echo "Done making documents" 6 | 7 | targetdir: 8 | @echo "Making $(TARGET_DIR)" 9 | mkdir -p ./Output 10 | 11 | createdocuments: 12 | python ./Setup/create_document.py windows main > ./Output/aws-CreateManagedWindowsInstance.json 13 | python ./Setup/create_document.py linux main > ./Output/aws-CreateManagedLinuxInstance.json 14 | python ./Setup/create_document.py windows approve > ./Output/aws-CreateManagedWindowsInstanceWithApproval.json 15 | python ./Setup/create_document.py linux approve > ./Output/aws-CreateManagedLinuxInstanceWithApproval.json 16 | 17 | test: documents 18 | python -m unittest discover Tests 19 | # python -m unittest Tests.test_ami_info.AmiInfoTest.test_handler_on_create_windows 20 | 21 | clean: 22 | @echo "Removing $(TARGET_DIR)" 23 | @rm -rf ./Output 24 | -------------------------------------------------------------------------------- /Documents/Automation/PatchWindowsInASG/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Patch Windows instances in an Auto Scaling Group 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ## Test script 8 | 9 | Python script will: 10 | 1. Create ASG with 2 instances (min:1, max: 2, desired: 2) 11 | 2. Create the Automation Document 12 | 3. Run the automation document against one of the instances 13 | 4. Poll the ASG and verify the instance enters standby 14 | 5. Verify the Automation completes with a successful status 15 | 6. Destroy the ASG 16 | -------------------------------------------------------------------------------- /Documents/Automation/PatchWindowsInASG/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Systems Manager Automation - Patch Windows instances in an Auto Scaling Group", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "AutomationAssumeRole": { 7 | "type": "String", 8 | "description": "The ARN of the role that allows Automation to perform the actions on your behalf.", 9 | "default": "" 10 | }, 11 | "InstanceID": { 12 | "type": "String", 13 | "description": "ID of the Windows Instance to patch. Only specify when not running from Maintenance Window.", 14 | "default": "{{TARGET_ID}}" 15 | }, 16 | "WaitForReboot": { 17 | "type": "String", 18 | "description": "(Optional) How long Automation should sleep for, to allow a patched instance to reboot", 19 | "default": "PT5M" 20 | }, 21 | "WaitForInstance": { 22 | "type": "String", 23 | "description": "(Optional) How long Automation should sleep for, to allow the instance come back into service", 24 | "default": "PT2M" 25 | } 26 | }, 27 | "mainSteps": [] 28 | } 29 | -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Reboot RDS Instance 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ### Steps 8 | 1. Create Stack (aws:createStack) 9 | * Input 10 | * LambdaAssumeRole - role lambda will be executed as. 11 | * Resources 12 | * Create RDS *reboot* Lambda 13 | * Create RDS *wait_for_state* Lambda 14 | * Create lambda role if LambdaAssumeRole is not provided. 15 | 2. Invoke *reboot* Lambda (aws:invokeLambdaFunction) 16 | * Input 17 | * RDS Instance Identifier 18 | * Steps 19 | * Reboot RDS instance. 20 | 3. Invoke *wait_for_state* Lambda (aws:invokeLambdaFunction) 21 | * Input 22 | * DB Instance Identifier 23 | * Accepted RDS state 24 | * Steps 25 | * Poll RDS instance information for state 26 | 4. Delete Stack (aws:deleteStack) 27 | 28 | 29 | ## Tests 30 | 31 | #### Document Test 32 | 1. Create resources using CFT 33 | * Create Automation Assume Role 34 | * Create RDS Instance 35 | 2. Execute Document 36 | 3. Verify RDS instance rebooted correctly 37 | 4. Tear down template 38 | 39 | ### Building Document 40 | 41 | ``` 42 | make 43 | ``` 44 | 45 | 1. Parse CloudFormation Template 46 | 2. Embed lambda functions located in Documents/Lambdas/ into CloudFormation Template 47 | A. reboot.py 48 | B. wait_for_state.py 49 | 3. Parse Documents/aws-RebootRds.json 50 | 4. Embed CloudFormation Template into Automation Document. 51 | 5. Output new Document into ./Output 52 | 53 | ### Cleaning Document 54 | 55 | ``` 56 | make clean 57 | ``` 58 | 59 | 1. Delete content of ./Output folder 60 | 61 | ### Test 62 | 63 | ``` 64 | make test 65 | ``` 66 | 67 | 1. Discover all test in this folder. 68 | 2. Execute all tests 69 | -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Reboot RDS Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) Identifies the *RDS* instance subject to action" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [] 22 | } -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Documents/Lambdas/reboot_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | instance_id = event["InstanceId"] 22 | rds_client = boto3.client('rds') 23 | instance_desc = rds_client.describe_db_instances(DBInstanceIdentifier=instance_id) 24 | instance_status = instance_desc["DBInstances"][0]["DBInstanceStatus"] 25 | if instance_status not in ["rebooting"]: 26 | rds_client.reboot_db_instance(DBInstanceIdentifier=instance_id) 27 | -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Documents/Lambdas/wait_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | import time 19 | 20 | rds_client = boto3.client('rds') 21 | 22 | 23 | def handler(event, context): 24 | instance_id = event["InstanceId"] 25 | wait_for_state = event["States"] 26 | 27 | while 1: 28 | try: 29 | info = rds_client.describe_db_instances( 30 | DBInstanceIdentifier=instance_id 31 | ) 32 | print info 33 | 34 | if info["DBInstances"][0]["DBInstanceStatus"] in wait_for_state: 35 | return 36 | 37 | time.sleep(10) 38 | except Exception as e: 39 | print e 40 | pass 41 | -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Documents/aws-RebootRdsInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Reboot RDS Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) Identifies the *RDS* instance subject to action" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "createDocumentStack", 24 | "action": "aws:createStack", 25 | "inputs": { 26 | "Capabilities": [ 27 | "CAPABILITY_IAM" 28 | ], 29 | "StackName": "RebootRdsInstanceStack{{automation:EXECUTION_ID}}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "LambdaRoleArn", 33 | "ParameterValue": "{{LambdaAssumeRole}}" 34 | }, 35 | { 36 | "ParameterKey": "RebootLambdaName", 37 | "ParameterValue": "RebootRdsInstanceLambda-{{automation:EXECUTION_ID}}" 38 | }, 39 | { 40 | "ParameterKey": "WaitLambdaName", 41 | "ParameterValue": "VerifyRdsLambda-{{automation:EXECUTION_ID}}" 42 | } 43 | ], 44 | "TemplateBody": "..." 45 | } 46 | }, 47 | { 48 | "name": "reboot", 49 | "action": "aws:invokeLambdaFunction", 50 | "inputs": { 51 | "FunctionName": "RebootRdsInstanceLambda-{{automation:EXECUTION_ID}}", 52 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\"}" 53 | } 54 | }, 55 | { 56 | "name": "wait_for_state", 57 | "action": "aws:invokeLambdaFunction", 58 | "maxAttempts": 10, 59 | "timeoutSeconds": 600, 60 | "onFailure": "Abort", 61 | "inputs": { 62 | "FunctionName": "VerifyRdsLambda-{{automation:EXECUTION_ID}}", 63 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"States\": [\"available\"]}" 64 | } 65 | }, 66 | { 67 | "name": "deleteCloudFormationTemplate", 68 | "action": "aws:deleteStack", 69 | "inputs": { 70 | "StackName": "RebootRdsInstanceStack{{automation:EXECUTION_ID}}" 71 | } 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-RebootRdsInstance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output -------------------------------------------------------------------------------- /Documents/Automation/RebootRds/README.md: -------------------------------------------------------------------------------- 1 | # Reboot RDS 2 | 3 | Reboots the **RDS** instance identified by operand *InstanceId*. 4 | 5 | ## Input 6 | 7 | #### InstanceId 8 | * Identifies the *RDS* instance subject to action 9 | * Type: String 10 | * Required: True 11 | 12 | 13 | ## Output 14 | The automation execution has no outputs. 15 | 16 | -------------------------------------------------------------------------------- /Documents/Automation/ResizeInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Resize Instance 2 | 3 | ## Notes 4 | 5 | Resize an instance by changing the instance type 6 | 7 | The bulk of the time spent is starting the instance. It takes approximately 5 minutes to restart the instance because it needs wait for the status check 8 | 9 | ## Document Design 10 | 11 | Refer to schema.json 12 | 13 | Document Steps: 14 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 15 | * Inputs: 16 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 17 | * Parameters: 18 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to resize an instance 19 | * LambdaName: ResizeInstanceLambda-{{automation:EXECUTION_ID}} 20 | 2. aws:changeInstanceState - Stops the instance. 21 | * Inputs: 22 | * InstanceIds: {{InstanceId}} - Instance ID to stop 23 | * DesiredState: 'stopped' 24 | 3. aws:invokeLambdaFunction - Execute Lambda to change the instance type of an instance 25 | * Inputs: 26 | * FunctionName: ResizeInstanceLambda-{{automation:EXECUTION_ID}} - Lambda name to use 27 | * Payload: 28 | * InstanceId: {{InstanceId}} - The ID of the instance. 29 | * InstanceType: {{InstanceType}} - The instance type. 30 | 4. aws:changeInstanceState - Restart the instance. 31 | * Inputs: 32 | * InstanceIds: {{InstanceId}} - Instance ID to start 33 | * DesiredState: 'running' 34 | 5. aws:deleteStack - Delete CloudFormation Template. 35 | * Inputs: 36 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 37 | 38 | ## Test script 39 | 40 | Python script will: 41 | 1. Create a test stack with an instance 42 | 2. Execute automation document to attach volume to instance 43 | 3. Verify instance type of a stack has changed 44 | 4. Verify instance is up 45 | 5. Clean up test stack 46 | -------------------------------------------------------------------------------- /Documents/Automation/ResizeInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Resize Instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) The ID of the instance." 9 | }, 10 | "InstanceType": { 11 | "type": "String", 12 | "description": "(Required) The instance type." 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role assumed by lambda", 17 | "default": "" 18 | }, 19 | "AutomationAssumeRole": { 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 22 | "default": "" 23 | } 24 | }, 25 | "mainSteps": [] 26 | } 27 | -------------------------------------------------------------------------------- /Documents/Automation/ResizeInstance/Documents/Lambdas/resize_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | instance_id = event["InstanceId"] 22 | new_instance_type = event["InstanceType"] 23 | 24 | ec2 = boto3.resource('ec2') 25 | instance = ec2.Instance(instance_id) 26 | 27 | # Migrated to a step 28 | # state_code = instance.state['Code'] 29 | # if state_code == 16 or state_code == 64: 30 | # instance.stop() 31 | # print "Stopping" 32 | # instance.wait_until_stopped() 33 | # print "Stopped" 34 | 35 | print "Modifying instance type" 36 | instance.modify_attribute(InstanceType={ 37 | 'Value': new_instance_type 38 | }) 39 | 40 | # Migrated to a step 41 | # instance.start() 42 | # print "Starting" 43 | # instance.wait_until_running() 44 | # print "Now running" 45 | 46 | -------------------------------------------------------------------------------- /Documents/Automation/ResizeInstance/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-ResizeInstance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Start EC2 instance based on ids or tags 2 | 3 | ## Notes 4 | 5 | Initial version will only support start via instance IDs (not tags) but will be updated after we have a lambda function 6 | that correctly determines InstanceIds from Tags and can pass those values to the next step in the Automation document. 7 | 8 | ## Document Design 9 | 10 | Refer to schema.json 11 | 12 | Document Steps: 13 | 1. aws:changeInstanceState 14 | * Inputs: 15 | * DesiredState: stopped 16 | * InstanceIds: {{InstanceId}} 17 | 2. aws:changeInstanceState 18 | * Inputs: 19 | * DesiredState: running 20 | * InstanceIds: {{InstanceId}} 21 | 22 | ## Test script 23 | 24 | Python script will: 25 | 1. Create 2 instances (instances 'a' & 'b') 26 | 2. Verify the EC2 instances are in the running state 27 | 3. Create the Automation Document, which will stop the instances and then subsequently start them again 28 | 4. Execute the document 29 | 5. Verify the instances are in a running state and that no errors were encountered when executing the Automation document 30 | 6. Destroy the instances and CloudFormation stack 31 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Restart EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to restart" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstance/Documents/aws-RestartEC2Instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Restart EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to restart" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "stopInstances", 19 | "action": "aws:changeInstanceState", 20 | "inputs": { 21 | "InstanceIds": "{{ InstanceId }}", 22 | "DesiredState": "stopped" 23 | } 24 | }, 25 | { 26 | "name": "startInstances", 27 | "action": "aws:changeInstanceState", 28 | "inputs": { 29 | "InstanceIds": "{{ InstanceId }}", 30 | "DesiredState": "running" 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstance/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - RestartInstance 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | Parameters: 30 | AMI: 31 | Description: AMI ID for instances. 32 | Type: String 33 | INSTANCETYPE: 34 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 35 | Type: String 36 | Resources: 37 | Instance0: 38 | Type: AWS::EC2::Instance 39 | Properties: 40 | ImageId: 41 | Ref: AMI 42 | InstanceType: 43 | Ref: INSTANCETYPE 44 | Instance1: 45 | Type: AWS::EC2::Instance 46 | Properties: 47 | ImageId: 48 | Ref: AMI 49 | InstanceType: 50 | Ref: INSTANCETYPE 51 | 52 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstanceWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Retart EC2 instance based on ids or tags while requiring approval from at least one specified user 2 | 3 | ## Notes 4 | 5 | Initial version will only support restart via instance IDs (not tags) but will be updated after we have a lambda function 6 | that correctly determines InstanceIds from Tags and can pass those values to the next step in the Automation document. 7 | 8 | ## Document Design 9 | 10 | Refer to schema.json 11 | 12 | Document Steps: 13 | 1. aws:approve 14 | * Inputs: 15 | * NotificationArn: {{SNSTopicArn}} 16 | * Message: "Please approve restarting the selected instance(s)" 17 | * MinRequiredApprovals: 1 18 | * Approvers: {{Approvers}} 19 | 2. aws:changeInstanceState 20 | * Inputs: 21 | * DesiredState: stopped 22 | * InstanceIds: {{InstanceId}} 23 | 3. aws:changeInstanceState 24 | * Inputs: 25 | * DesiredState: running 26 | * InstanceIds: {{InstanceId}} 27 | 28 | ## Test script 29 | 30 | Python script will: 31 | 1. Create 2 instances (instances 'a' & 'b') 32 | 2. Verify the EC2 instances are in the running state 33 | 3. Create the Automation Document 34 | 4. Execute the document, which will go into the Waiting state pending approval 35 | 5. Send the Approve signal via ssm_client.send_automation_signal() method, which will allow the automation to continue 36 | 6. Verify the instances are in a running state and that no errors were encountered when executing the Automation document 37 | 7. Destroy the instances and CloudFormation stack 38 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstanceWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Restart EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to restart" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for instance restart. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstanceWithApproval/Documents/aws-RestartEC2Instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Restart EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to restart" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for instance restart. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "approve", 27 | "action": "aws:approve", 28 | "onFailure": "Abort", 29 | "inputs": { 30 | "NotificationArn": "{{ SNSTopicArn }}", 31 | "Message": "Approval required to restart EC2 instances", 32 | "MinRequiredApprovals": 1, 33 | "Approvers": "{{ Approvers }}" 34 | } 35 | }, 36 | { 37 | "name": "stopInstances", 38 | "action": "aws:changeInstanceState", 39 | "inputs": { 40 | "InstanceIds": "{{ InstanceId }}", 41 | "DesiredState": "stopped" 42 | } 43 | }, 44 | { 45 | "name": "startInstances", 46 | "action": "aws:changeInstanceState", 47 | "inputs": { 48 | "InstanceIds": "{{ InstanceId }}", 49 | "DesiredState": "running" 50 | } 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /Documents/Automation/RestartInstanceWithApproval/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - RestartInstanceWithApproval 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | SNSTopicArn: 30 | Description: ARN for the created SNS topic 31 | Value: 32 | Ref: SNSTopic 33 | Parameters: 34 | AMI: 35 | Description: AMI ID for instances. 36 | Type: String 37 | INSTANCETYPE: 38 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 39 | Type: String 40 | Resources: 41 | SNSTopic: 42 | Type: AWS::SNS::Topic 43 | Properties: 44 | DisplayName: Automation Approval Topic for Restarting EC2 Instances 45 | TopicName: Automation_Restart_Instances_Approval 46 | Instance0: 47 | Type: AWS::EC2::Instance 48 | Properties: 49 | ImageId: 50 | Ref: AMI 51 | InstanceType: 52 | Ref: INSTANCETYPE 53 | Instance1: 54 | Type: AWS::EC2::Instance 55 | Properties: 56 | ImageId: 57 | Ref: AMI 58 | InstanceType: 59 | Ref: INSTANCETYPE 60 | 61 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Start EC2 instance based on ids or tags 2 | 3 | ## Notes 4 | 5 | Initial version will only support start via instance IDs (not tags) to avoid Lambda use in first document. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:changeInstanceState 13 | * Inputs: 14 | * DesiredState: running 15 | * InstanceIds: {{InstanceId}} 16 | 17 | ## Test script 18 | 19 | Python script will: 20 | 1. Create 3 instances (instances 'a', 'b', & 'c') 21 | 2. Stop the 3 instances 22 | 3. Create the Automation Document 23 | 4. Execute the document twice: once for instance 'a' (to test invocation with a single instance), and again for instances 'b' & 'c' (to test a list of instances) 24 | 5. Verify the instances are in a running state 25 | 6. Destroy the instances 26 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to start" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstance/Documents/aws-StartEC2Instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to start" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "startInstances", 19 | "action": "aws:changeInstanceState", 20 | "inputs": { 21 | "InstanceIds": "{{ InstanceId }}", 22 | "DesiredState": "running" 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstance/Tests/CloudFormationTemplates/ThreeInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | AWSTemplateFormatVersion: "2010-09-09" 18 | Description: "Test stack for SSM Automation - StartInstance" 19 | Outputs: 20 | Instance0Id: 21 | Description: "Instance Id" 22 | Value: 23 | Ref: Instance0 24 | Instance1Id: 25 | Description: "Instance Id" 26 | Value: 27 | Ref: Instance1 28 | Instance2Id: 29 | Description: "Instance Id" 30 | Value: 31 | Ref: Instance2 32 | Parameters: 33 | AMI: 34 | Description: "AMI ID for instances." 35 | Type: String 36 | INSTANCETYPE: 37 | Description: "AMI Instance Type (t2.micro, m1.large, etc.)" 38 | Type: String 39 | Resources: 40 | Instance0: 41 | Type: "AWS::EC2::Instance" 42 | Properties: 43 | ImageId: 44 | Ref: AMI 45 | InstanceType: 46 | Ref: INSTANCETYPE 47 | Instance1: 48 | Type: "AWS::EC2::Instance" 49 | Properties: 50 | ImageId: 51 | Ref: AMI 52 | InstanceType: 53 | Ref: INSTANCETYPE 54 | Instance2: 55 | Type: "AWS::EC2::Instance" 56 | Properties: 57 | ImageId: 58 | Ref: AMI 59 | InstanceType: 60 | Ref: INSTANCETYPE 61 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstanceWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Start EC2 instances with approval 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | Document Steps: 8 | 1. aws:approve 9 | * Inputs: 10 | * NotificationArn: {{SNSTopicArn}} 11 | * Message: "Please approve the start of the selected instance(s)" 12 | * MinRequiredApprovals: 1 13 | * Approvers: {{Approvers}} 14 | 2. aws:changeInstanceState 15 | * Inputs: 16 | * DesiredState: running 17 | * InstanceIds: {{InstanceId}} 18 | 19 | ## Test script 20 | 21 | Python script will: 22 | 1. Create 2 instances (instances 'a' & 'b') & a dummy SNS topic using a CloudFormation template 23 | 2. Stop the 2 instances 24 | 3. Create the Automation Document 25 | 4. Execute the automation document 26 | 5. Use ssm_client.send_automation_signal with SignalType 'Approve' to automatically approve the execution 27 | 6. Verify the instances are in a running state 28 | 7. Destroy the instances, delete the Automation Document, and delete the dummy SNS topic 29 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstanceWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to start" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for start instance action. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstanceWithApproval/Documents/aws-StartEC2InstanceWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to start" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for start instance action. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "approve", 27 | "action": "aws:approve", 28 | "onFailure": "Abort", 29 | "inputs": { 30 | "NotificationArn": "{{ SNSTopicArn }}", 31 | "Message": "Approval required to start EC2 instances", 32 | "MinRequiredApprovals": 1, 33 | "Approvers": "{{ Approvers }}" 34 | } 35 | }, 36 | { 37 | "name": "startInstances", 38 | "action": "aws:changeInstanceState", 39 | "inputs": { 40 | "InstanceIds": "{{ InstanceId }}", 41 | "DesiredState": "running" 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /Documents/Automation/StartInstanceWithApproval/Tests/CloudFormationTemplates/TwoInstancesWithSNS.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | AWSTemplateFormatVersion: "2010-09-09" 18 | Description: "Test stack for SSM Automation - StartInstanceWithApproval" 19 | Outputs: 20 | Instance0Id: 21 | Description: "Instance Id" 22 | Value: 23 | Ref: Instance0 24 | Instance1Id: 25 | Description: "Instance Id" 26 | Value: 27 | Ref: Instance1 28 | SNSTopicArn: 29 | Description: "ARN for the created SNS topic" 30 | Value: 31 | Ref: SNSTopic 32 | Parameters: 33 | AMI: 34 | Description: "AMI ID for instances." 35 | Type: String 36 | INSTANCETYPE: 37 | Description: "AMI Instance Type (t2.micro, m1.large, etc.)" 38 | Type: String 39 | Resources: 40 | SNSTopic: 41 | Type: "AWS::SNS::Topic" 42 | Properties: 43 | DisplayName: "Automation Approval Topic for Starting EC2 Instances" 44 | TopicName: Automation_Start_Instances_Approval 45 | Instance0: 46 | Type: "AWS::EC2::Instance" 47 | Properties: 48 | ImageId: 49 | Ref: AMI 50 | InstanceType: 51 | Ref: INSTANCETYPE 52 | Instance1: 53 | Type: "AWS::EC2::Instance" 54 | Properties: 55 | ImageId: 56 | Ref: AMI 57 | InstanceType: 58 | Ref: INSTANCETYPE 59 | -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Start RDS instance based on InstanceId 2 | 3 | ## Document Design 4 | 5 | ### Inputs 6 | * (Required) Database Instance Identifier. 7 | * (Optional) The ARN of the role assumed by lambda. 8 | * (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. 9 | 10 | ### Steps 11 | 1. Create Stack (aws:createStack) 12 | * Input 13 | * LambdaAssumeRole - role lambda will be executed as. 14 | * Resources 15 | * Create RDS create-instance Lambda 16 | * Create RDS stop-instance Lambda 17 | * Create lambda role if LambdaAssumeRole is not provided. 18 | 2. Invoke RDS start Lambda (aws:invokeLambdaFunction) 19 | * Input 20 | * DB Instance Identifier 21 | * Steps 22 | * Start RDS instance. 23 | 3. Invoke RDS start Lambda (aws:invokeLambdaFunction) 24 | * Input 25 | * DB Instance Identifier 26 | * Accepted RDS state 27 | * Steps 28 | * Poll RDS instance information for state 29 | 4. Delete Stack (aws:deleteStack) 30 | 31 | 32 | ### Test 33 | 34 | #### Document Test 35 | 1. Create resources using CFT 36 | * Create Automation Assume Role 37 | * Create RDS Instance 38 | * Stop RDS Instance 39 | 2. Execute Document 40 | 3. Verify RDS instance started correctly 41 | 4. Tear down template 42 | -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start RDS instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) RDS InstanceId to start" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [] 22 | } -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Documents/Lambdas/start_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | instance_id = event["InstanceId"] 22 | rds_client = boto3.client('rds') 23 | instance_desc = rds_client.describe_db_instances(DBInstanceIdentifier=instance_id) 24 | instance_status = instance_desc["DBInstances"][0]["DBInstanceStatus"] 25 | if instance_status not in ["available", "starting"]: 26 | rds_client.start_db_instance(DBInstanceIdentifier=instance_id) 27 | -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Documents/Lambdas/wait_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | import time 19 | 20 | rds_client = boto3.client('rds') 21 | 22 | def handler(event, context): 23 | instance_id = event["InstanceId"] 24 | wait_for_state = event["States"] 25 | 26 | while 1: 27 | try: 28 | info = rds_client.describe_db_instances( 29 | DBInstanceIdentifier=instance_id 30 | ) 31 | print info 32 | 33 | if info["DBInstances"][0]["DBInstanceStatus"] in wait_for_state: 34 | return 35 | 36 | time.sleep(10) 37 | except Exception as e: 38 | print e 39 | pass 40 | -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Documents/aws-StartRdsInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Start RDS instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) RDS Instance Id to start" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "createDocumentStack", 24 | "action": "aws:createStack", 25 | "inputs": { 26 | "Capabilities": [ 27 | "CAPABILITY_IAM" 28 | ], 29 | "StackName": "StartRdsInstanceStack{{automation:EXECUTION_ID}}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "LambdaRoleArn", 33 | "ParameterValue": "{{LambdaAssumeRole}}" 34 | }, 35 | { 36 | "ParameterKey": "LambdaName", 37 | "ParameterValue": "StartRdsInstanceLambda-{{automation:EXECUTION_ID}}" 38 | }, 39 | { 40 | "ParameterKey": "WaitLambdaName", 41 | "ParameterValue": "VerifyRdsLambda-{{automation:EXECUTION_ID}}" 42 | } 43 | ], 44 | "TemplateBody": "..." 45 | } 46 | }, 47 | { 48 | "name": "startInstance", 49 | "action": "aws:invokeLambdaFunction", 50 | "inputs": { 51 | "FunctionName": "StartRdsInstanceLambda-{{automation:EXECUTION_ID}}", 52 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\"}" 53 | } 54 | }, 55 | { 56 | "name": "checkStart", 57 | "action": "aws:invokeLambdaFunction", 58 | "maxAttempts": 10, 59 | "timeoutSeconds": 600, 60 | "onFailure": "Abort", 61 | "inputs": { 62 | "FunctionName": "VerifyRdsLambda-{{automation:EXECUTION_ID}}", 63 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"States\": [\"available\"]}" 64 | } 65 | }, 66 | { 67 | "name": "deleteCloudFormationTemplate", 68 | "action": "aws:deleteStack", 69 | "inputs": { 70 | "StackName": "StartRdsInstanceStack{{automation:EXECUTION_ID}}" 71 | } 72 | } 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-StartRdsInstance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output -------------------------------------------------------------------------------- /Documents/Automation/StartRdsInstance/README.md: -------------------------------------------------------------------------------- 1 | # Start RDS Instance 2 | 3 | Starts a DB instance that was stopped using the AWS console, the stop-db-instance AWS CLI command, the StopRds 4 | Automation Document or the stop-db-instance action. 5 | 6 | ## Inputs 7 | 8 | #### InstanceId 9 | * The RDS instance to start. 10 | * Type: String 11 | * Required: True 12 | 13 | ## Outputs 14 | The automation execution has no outputs. 15 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Stop EC2 instance based on ids or tags 2 | 3 | ## Notes 4 | 5 | Initial version will only support stop via instance IDs (not tags) to avoid Lambda use. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:changeInstanceState 13 | * Inputs: 14 | * DesiredState: stopped 15 | * InstanceIds: {{InstanceId}} 16 | 17 | ## Test script 18 | 19 | Python script will: 20 | 1. Create 2 instances (instances 'a' & 'b') 21 | 2. Stop the 2 instances 22 | 3. Create the Automation Document 23 | 4. Execute the document for instances 'a' & 'b' (to test a list of instances) 24 | 5. Verify the instances are in the 'stopped' state 25 | 6. Destroy the instances 26 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to stop" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstance/Documents/aws-StopEC2Instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to stop" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "stopInstances", 19 | "action": "aws:changeInstanceState", 20 | "onFailure": "Continue", 21 | "inputs": { 22 | "InstanceIds": "{{ InstanceId }}", 23 | "DesiredState": "stopped" 24 | } 25 | }, 26 | { 27 | "name": "forceStopInstances", 28 | "action": "aws:changeInstanceState", 29 | "inputs": { 30 | "InstanceIds": "{{ InstanceId }}", 31 | "CheckStateOnly": false, 32 | "DesiredState": "stopped", 33 | "Force": true 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstance/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - StopInstance 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | Parameters: 30 | AMI: 31 | Description: AMI ID for instances. 32 | Type: String 33 | INSTANCETYPE: 34 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 35 | Type: String 36 | Resources: 37 | Instance0: 38 | Type: AWS::EC2::Instance 39 | Properties: 40 | ImageId: 41 | Ref: AMI 42 | InstanceType: 43 | Ref: INSTANCETYPE 44 | Instance1: 45 | Type: AWS::EC2::Instance 46 | Properties: 47 | ImageId: 48 | Ref: AMI 49 | InstanceType: 50 | Ref: INSTANCETYPE 51 | 52 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstanceWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Stop EC2 instances with approval 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | Document Steps: 8 | 1. aws:approve 9 | * Inputs: 10 | * NotificationArn: {{SNSTopicArn}} 11 | * Message: "Please approve stopping the selected instance(s)" 12 | * MinRequiredApprovals: 1 13 | * Approvers: {{Approvers}} 14 | 2. aws:changeInstanceState 15 | * Inputs: 16 | * DesiredState: stopped 17 | * InstanceIds: {{InstanceId}} 18 | 19 | ## Test script 20 | 21 | Python script will: 22 | 1. Create 2 instances (instances 'a' & 'b') & a dummy SNS topic using a CloudFormation template 23 | 2. Verify that the instances are in the running state 24 | 3. Create the Automation Document 25 | 4. Execute the automation document 26 | 5. Use ssm_client.send_automation_signal with SignalType 'Approve' to automatically approve the execution 27 | 6. Verify the instances are in a stopped state 28 | 7. Destroy the instances, delete the Automation Document, and delete the dummy SNS topic 29 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstanceWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to stop" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for stop instance action. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstanceWithApproval/Documents/aws-StopEC2InstanceWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to stop" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for stop instance action. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "approve", 27 | "action": "aws:approve", 28 | "onFailure": "Abort", 29 | "inputs": { 30 | "NotificationArn": "{{ SNSTopicArn }}", 31 | "Message": "Approval required to stop running EC2 instances", 32 | "MinRequiredApprovals": 1, 33 | "Approvers": "{{ Approvers }}" 34 | } 35 | }, 36 | { 37 | "name": "stopInstances", 38 | "action": "aws:changeInstanceState", 39 | "onFailure": "Continue", 40 | "inputs": { 41 | "InstanceIds": "{{ InstanceId }}", 42 | "DesiredState": "stopped" 43 | } 44 | }, 45 | { 46 | "name": "forceStopInstances", 47 | "action": "aws:changeInstanceState", 48 | "inputs": { 49 | "InstanceIds": "{{ InstanceId }}", 50 | "CheckStateOnly": false, 51 | "DesiredState": "stopped", 52 | "Force": true 53 | } 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /Documents/Automation/StopInstanceWithApproval/Tests/CloudFormationTemplates/TwoInstancesWithSNS.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | AWSTemplateFormatVersion: "2010-09-09" 18 | Description: "Test stack for SSM Automation - StopInstanceWithApproval" 19 | Outputs: 20 | Instance0Id: 21 | Description: "Instance Id" 22 | Value: 23 | Ref: Instance0 24 | Instance1Id: 25 | Description: "Instance Id" 26 | Value: 27 | Ref: Instance1 28 | SNSTopicArn: 29 | Description: "ARN for the created SNS topic" 30 | Value: 31 | Ref: SNSTopic 32 | Parameters: 33 | AMI: 34 | Description: "AMI ID for instances." 35 | Type: String 36 | INSTANCETYPE: 37 | Description: "AMI Instance Type (t2.micro, m1.large, etc.)" 38 | Type: String 39 | Resources: 40 | SNSTopic: 41 | Type: "AWS::SNS::Topic" 42 | Properties: 43 | DisplayName: "Automation Approval Topic for Stopping EC2 Instances" 44 | TopicName: Automation_Stop_Instances_Approval 45 | Instance0: 46 | Type: "AWS::EC2::Instance" 47 | Properties: 48 | ImageId: 49 | Ref: AMI 50 | InstanceType: 51 | Ref: INSTANCETYPE 52 | Instance1: 53 | Type: "AWS::EC2::Instance" 54 | Properties: 55 | ImageId: 56 | Ref: AMI 57 | InstanceType: 58 | Ref: INSTANCETYPE 59 | -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Stop RDS instance based on id 2 | 3 | ## Notes 4 | 5 | ## Document Design 6 | 7 | ### Inputs 8 | 9 | * (Required) Database Instance Identifier. 10 | * (Optional) The ARN of the role assumed by lambda. 11 | * (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. 12 | 13 | ### Steps 14 | 15 | 1. Create Stack (aws:createStack) 16 | * Input 17 | * LambdaAssumeRole - role lambda will be executed as. 18 | * Resources 19 | * Create RDS start Lambda 20 | * Create lambda role if LambdaAssumeRole is not provided. 21 | 2. Invoke RDS start Lambda (aws:invokeLambdaFunction) 22 | * Input 23 | * DB Instance Identifier 24 | * Steps 25 | * Stop RDS instance. 26 | 3. Invoke RDS wait lambda (aws:invokeLambdaFunction) 27 | * Input 28 | * DB Instance Identifier 29 | * Accepted RDS state 30 | 3. Delete Stack (aws:deleteStack) 31 | 32 | ### Test 33 | 34 | #### Document Test 35 | 36 | 1. Create resources using CFT 37 | * Create Automation Assume Role 38 | * Create RDS Instance 39 | 2. Execute Document 40 | 3. Verify RDS instance stopped correctly 41 | 4. Tear down template -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop RDS instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) RDS InstanceId to stop" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [] 22 | } 23 | -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Documents/Lambdas/stop_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | instance_id = event["InstanceId"] 22 | rds_client = boto3.client('rds') 23 | instance_desc = rds_client.describe_db_instances(DBInstanceIdentifier=instance_id) 24 | instance_status = instance_desc["DBInstances"][0]["DBInstanceStatus"] 25 | 26 | if instance_status not in ["stopped", "stopping"]: 27 | rds_client.stop_db_instance( 28 | DBInstanceIdentifier=instance_id 29 | ) 30 | -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Documents/Lambdas/wait_rds_instance.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | import time 19 | 20 | rds_client = boto3.client('rds') 21 | 22 | 23 | def handler(event, context): 24 | instance_id = event["InstanceId"] 25 | wait_for_state = event["States"] 26 | 27 | while 1: 28 | try: 29 | info = rds_client.describe_db_instances( 30 | DBInstanceIdentifier=instance_id 31 | ) 32 | print info 33 | 34 | if info["DBInstances"][0]["DBInstanceStatus"] in wait_for_state: 35 | return 36 | 37 | time.sleep(10) 38 | except Exception as e: 39 | print e 40 | pass -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Documents/aws-StopRdsInstance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Stop RDS instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) RDS Instance Id to stop" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | }, 15 | "LambdaAssumeRole": { 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role assumed by lambda", 18 | "default": "" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "name": "createDocumentStack", 24 | "action": "aws:createStack", 25 | "inputs": { 26 | "Capabilities": [ 27 | "CAPABILITY_IAM" 28 | ], 29 | "StackName": "StopRdsInstanceStack{{automation:EXECUTION_ID}}", 30 | "Parameters": [ 31 | { 32 | "ParameterKey": "LambdaRoleArn", 33 | "ParameterValue": "{{LambdaAssumeRole}}" 34 | }, 35 | { 36 | "ParameterKey": "LambdaName", 37 | "ParameterValue": "StopRdsInstanceLambda-{{automation:EXECUTION_ID}}" 38 | }, 39 | { 40 | "ParameterKey": "WaitLambdaName", 41 | "ParameterValue": "VerifyRdsLambda-{{automation:EXECUTION_ID}}" 42 | } 43 | ], 44 | "TemplateBody": "..." 45 | } 46 | }, 47 | { 48 | "name": "stopInstance", 49 | "action": "aws:invokeLambdaFunction", 50 | "inputs": { 51 | "FunctionName": "StopRdsInstanceLambda-{{automation:EXECUTION_ID}}", 52 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\"}" 53 | } 54 | }, 55 | { 56 | "name": "checkStop", 57 | "action": "aws:invokeLambdaFunction", 58 | "maxAttempts": 10, 59 | "timeoutSeconds": 600, 60 | "onFailure": "Abort", 61 | "inputs": { 62 | "FunctionName": "VerifyRdsLambda-{{automation:EXECUTION_ID}}", 63 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"States\": [\"stopped\"]}" 64 | } 65 | }, 66 | { 67 | "name": "deleteCloudFormationTemplate", 68 | "action": "aws:deleteStack", 69 | "inputs": { 70 | "StackName": "StopRdsInstanceStack{{automation:EXECUTION_ID}}" 71 | } 72 | } 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-StopRdsInstance.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/StopRdsInstance/README.md: -------------------------------------------------------------------------------- 1 | # Stop RDS Instance 2 | 3 | Stops a DB instance. When you stop a DB instance, Amazon RDS retains the DB instance's metadata, including its endpoint, 4 | DB parameter group, and option group membership. Amazon RDS also retains the transaction logs so you can do a 5 | point-in-time restore if necessary. 6 | 7 | ## Inputs 8 | 9 | #### InstanceId 10 | * The RDS instance to stop. 11 | * Type: String 12 | * Required: True 13 | 14 | ## Outputs 15 | The automation execution has no outputs. 16 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstance/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Terminate EC2 instance based on ids or tags 2 | 3 | ## Notes 4 | 5 | Initial version will only support termination via instance IDs (not tags) to avoid Lambda use. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:changeInstanceState 13 | * Inputs: 14 | * DesiredState: terminated 15 | * InstanceIds: {{InstanceId}} 16 | 17 | ## Test script 18 | 19 | Python script will: 20 | 1. Create 2 instances (instances 'a' & 'b') via CloudFormation template, which will start the instances automatically 21 | 2. Create the Automation Document 22 | 3. Execute the document for instances 'a' & 'b' 23 | 4. Verify the instances are in the 'terminated' state and that the automation execution status is marked 'Success' 24 | 5. Tear down the CloudFormation stack 25 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstance/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Terminate EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to terminate" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [] 17 | } 18 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstance/Documents/aws-TerminateEC2Instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Terminate EC2 instances(s)", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to terminate" 9 | }, 10 | "AutomationAssumeRole": { 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 13 | "default": "" 14 | } 15 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "stopInstances", 19 | "action": "aws:changeInstanceState", 20 | "inputs": { 21 | "InstanceIds": "{{ InstanceId }}", 22 | "DesiredState": "terminated" 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstance/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - TerminateInstance 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | Parameters: 30 | AMI: 31 | Description: AMI ID for instances. 32 | Type: String 33 | INSTANCETYPE: 34 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 35 | Type: String 36 | Resources: 37 | Instance0: 38 | Type: AWS::EC2::Instance 39 | Properties: 40 | ImageId: 41 | Ref: AMI 42 | InstanceType: 43 | Ref: INSTANCETYPE 44 | Instance1: 45 | Type: AWS::EC2::Instance 46 | Properties: 47 | ImageId: 48 | Ref: AMI 49 | InstanceType: 50 | Ref: INSTANCETYPE 51 | 52 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstanceWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Terminate EC2 instance based on ids or tags with approval 2 | 3 | ## Notes 4 | 5 | Initial version will only support termination via instance IDs (not tags) to avoid Lambda use. 6 | 7 | ## Document Design 8 | 9 | Refer to schema.json 10 | 11 | Document Steps: 12 | 1. aws:approve 13 | * Inputs: 14 | * NotificationArn: {{SNSTopicArn}} 15 | * Message: "Please approve terminating the selected instance(s)" 16 | * MinRequiredApprovals: 1 17 | * Approvers: {{Approvers}} 18 | 2. aws:changeInstanceState 19 | * Inputs: 20 | * DesiredState: terminated 21 | * InstanceIds: {{InstanceId}} 22 | 23 | ## Test script 24 | 25 | Python script will: 26 | 1. Create 2 instances (instances 'a' & 'b') via CloudFormation template, which will start the instances automatically 27 | 2. Create the Automation Document 28 | 3. Execute the document for instances 'a' & 'b' 29 | 4. Check that the automation execution enters the Waiting state (pending approval) 30 | 5. Use ssm_client.send_automation_signal with SignalType 'Approve' to programmatically approve the execution 31 | 6. Wait until the automation execution completes with a status of 'Success' 32 | 7. Verify that the EC2 instances are now in the terminated state 33 | 8. Tear down the CloudFormation stack 34 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstanceWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Terminate EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to terminate" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for instance termination. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } 26 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstanceWithApproval/Documents/aws-TerminateEC2InstanceWithApproval.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Terminate EC2 instances(s) with approval", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "StringList", 8 | "description": "(Required) EC2 Instance(s) to terminate" 9 | }, 10 | "Approvers": { 11 | "type": "StringList", 12 | "description": "(Required) IAM user or user arn of approvers for the automation action" 13 | }, 14 | "SNSTopicArn": { 15 | "type": "String", 16 | "description": "(Required) The SNS topic ARN used to send pending approval notification for instance termination. The SNS topic name must start with Automation." 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "approve", 27 | "action": "aws:approve", 28 | "onFailure": "Abort", 29 | "inputs": { 30 | "NotificationArn": "{{ SNSTopicArn }}", 31 | "Message": "Approval required to terminate running EC2 instances", 32 | "MinRequiredApprovals": 1, 33 | "Approvers": "{{ Approvers }}" 34 | } 35 | }, 36 | { 37 | "name": "stopInstances", 38 | "action": "aws:changeInstanceState", 39 | "inputs": { 40 | "InstanceIds": "{{ InstanceId }}", 41 | "DesiredState": "terminated" 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /Documents/Automation/TerminateInstanceWithApproval/Tests/CloudFormationTemplates/TwoInstances.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test stack for SSM Automation - TerminateInstanceWithApproval 20 | Outputs: 21 | Instance0Id: 22 | Description: Instance Id 23 | Value: 24 | Ref: Instance0 25 | Instance1Id: 26 | Description: Instance Id 27 | Value: 28 | Ref: Instance1 29 | SNSTopicArn: 30 | Description: ARN for the created SNS topic 31 | Value: 32 | Ref: SNSTopic 33 | Parameters: 34 | AMI: 35 | Description: AMI ID for instances. 36 | Type: String 37 | INSTANCETYPE: 38 | Description: AMI Instance Type (t2.micro, m1.large, etc.) 39 | Type: String 40 | Resources: 41 | SNSTopic: 42 | Type: AWS::SNS::Topic 43 | Properties: 44 | DisplayName: Automation Approval Topic for Terminating EC2 Instances 45 | TopicName: Automation_Terminate_Instances_Approval 46 | Instance0: 47 | Type: AWS::EC2::Instance 48 | Properties: 49 | ImageId: 50 | Ref: AMI 51 | InstanceType: 52 | Ref: INSTANCETYPE 53 | Instance1: 54 | Type: AWS::EC2::Instance 55 | Properties: 56 | ImageId: 57 | Ref: AMI 58 | InstanceType: 59 | Ref: INSTANCETYPE 60 | 61 | -------------------------------------------------------------------------------- /Documents/Automation/Testing/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | -------------------------------------------------------------------------------- /Documents/Automation/Testing/defaults.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | region = us-east-1 3 | automation_service_role_name = AutomationServiceRole 4 | log_level = warn 5 | # prepended to document & stack names 6 | resource_prefix = testing- 7 | 8 | [linux] 9 | # Amazon Linux 2017.09.0; any linux will work 10 | ami = ami-97785bed 11 | instance_type = t2.micro 12 | 13 | [windows] 14 | instance_type = t2.micro 15 | # Microsoft Windows Server 2016 Base 2017.09.13 16 | windows2016.us-east-1 = ami-603b1c1a 17 | windows2016.us-east-2 = ami-d3e7c5b6 18 | windows2016.us-west-1 = ami-32320452 19 | windows2016.us-west-2 = ami-47897a3f 20 | windows2016.ca-central-1 = ami-58c1783c 21 | windows2016.eu-central-1 = ami-29fd4b46 22 | windows2016.eu-west-1 = ami-e92fec90 23 | windows2016.eu-west-2 = ami-6c021108 24 | windows2016.ap-southeast-1 = ami-1c61147f 25 | windows2016.ap-southeast-2 = ami-663bdc04 26 | windows2016.ap-northeast-1 = ami-de8d40b8 27 | windows2016.ap-northeast-2 = ami-073be069 28 | windows2016.sa-east-1 = ami-1d364b71 29 | windows2016.ap-south-1 = ami-6af0b705 -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Update CloudFormation Template 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ### Steps 8 | 9 | 1. aws:createStack - Execute CloudFormation Template to create lambda. 10 | * Inputs: 11 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 12 | * Parameters: 13 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to update the CloudFormation Template. 14 | * LambdaName: UpdateCFTemplate-{{automation:EXECUTION_ID}} 15 | 2. aws:invokeLambdaFunction - Execute Lambda to update CloudFormationTemplate. 16 | * Inputs: 17 | * FunctionName: UpdateCFTemplate-{{automation:EXECUTION_ID}} - Lambda name to use 18 | * Payload: 19 | * StackName: {{StackName}} - Stack to update 20 | * TemplateLocation: {{TemplateLocation}} - Location of template (e.g. https://s3.amazonaws.com/example/updated.template) 21 | 3. aws:deleteStack - Delete CloudFormation Template. 22 | * Inputs: 23 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 24 | 25 | ### CloudFormation Template 26 | 27 | Creates Lambda used by the SSM document to update the CloudFormation Template 28 | 29 | #### Resources 30 | 31 | * IAM Role - Role used by lambda (only created if non specified by user {{LambdaRoleArn}}) 32 | * Lambda - does the actual work to update the CloudFormation Template. 33 | 34 | ## Tests 35 | 36 | ### test_update_formation_template.py 37 | 38 | Tests updating cloudformation template at the lambda level. 39 | 40 | ### test_document.py 41 | 42 | Full SSM integration test. 43 | 44 | 1. Create a bucket for test in us-west-2 45 | 2. Deploy CloudFormation Template in us-east-1 46 | * Create IAM Role 47 | 3. Upload updated CloudFormation template to test bucket in us-west-2 48 | * Add another policy to the IAM Role. 49 | 4. Execute SSM document to update CloudFormation Template. 50 | 5. Validate document executed correctly. 51 | 6. Validate new policy was added to IAM Role. 52 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "CloudFormation Template Update - Manage updating CloudFormation Template from a S3 bucket.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be updated" 9 | }, 10 | "TemplateUrl": { 11 | "type": "String", 12 | "description": "(Required) S3 bucket location of updated CloudFormation Template (e.g. https://s3.amazonaws.com/example/updated.template)" 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Required) The ARN of the role assumed by lambda" 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [] 25 | } -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Documents/CloudFormationTemplates/UpdateCFTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Parameters: 20 | LambdaRoleArn: 21 | Description: > 22 | The ARN of the role that allows Lambda created by Automation to perform the action on your behalf 23 | Type: String 24 | Default: "" 25 | LambdaName: 26 | Description: > 27 | The lambda function name 28 | Type: String 29 | Resources: 30 | UpdateCFLambda: 31 | Type: AWS::Lambda::Function 32 | Properties: 33 | Code: 34 | ZipFile: "{}" 35 | FunctionName: !Ref LambdaName 36 | Role: !Ref LambdaRoleArn 37 | Timeout: 60 38 | Handler: "index.handler" 39 | Runtime: python2.7 40 | MemorySize: 128 41 | 42 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Documents/Lambdas/update_cf_template.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | cf = boto3.client("cloudformation") 22 | 23 | cf.update_stack( 24 | StackName=event["StackName"], 25 | TemplateURL=event["TemplateUrl"], 26 | Capabilities=["CAPABILITY_IAM"] 27 | ) 28 | 29 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Documents/aws-UpdateCloudFormationTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "CloudFormation Template Update - Manage updating CloudFormation Template from a S3 bucket.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be updated" 9 | }, 10 | "TemplateUrl": { 11 | "type": "String", 12 | "description": "(Required) S3 bucket location of updated CloudFormation Template (e.g. https://s3.amazonaws.com/example/updated.template)" 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Required) The ARN of the role assumed by lambda" 17 | }, 18 | "AutomationAssumeRole": { 19 | "type": "String", 20 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "name": "createDocumentStack", 27 | "action": "aws:createStack", 28 | "inputs": { 29 | "Capabilities": [ 30 | "CAPABILITY_IAM" 31 | ], 32 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}", 33 | "Parameters": [ 34 | { 35 | "ParameterKey": "LambdaRoleArn", 36 | "ParameterValue": "{{LambdaAssumeRole}}" 37 | }, 38 | { 39 | "ParameterKey": "LambdaName", 40 | "ParameterValue": "UpdateCFTemplate-{{automation:EXECUTION_ID}}" 41 | } 42 | ], 43 | "TemplateBody": "..." 44 | } 45 | }, 46 | { 47 | "name": "updateCloudFormationTemplate", 48 | "action": "aws:invokeLambdaFunction", 49 | "inputs": { 50 | "FunctionName": "UpdateCFTemplate-{{automation:EXECUTION_ID}}", 51 | "Payload": "{\"StackName\": \"{{StackNameOrId}}\", \"TemplateUrl\": \"{{TemplateUrl}}\"}" 52 | } 53 | }, 54 | { 55 | "name": "deleteCloudFormationTemplate", 56 | "action": "aws:deleteStack", 57 | "inputs": { 58 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}" 59 | } 60 | } 61 | ] 62 | } -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-UpdateCloudFormationTemplate.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Tests/CloudFormationTemplates/TestTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test template for UpdateCloudFormationTemplate 20 | Resources: 21 | TestRole: 22 | Type: AWS::IAM::Role 23 | Properties: 24 | AssumeRolePolicyDocument: 25 | Version: "2012-10-17" 26 | Statement: 27 | - Action: ["sts:AssumeRole"] 28 | Effect: "Allow" 29 | Principal: 30 | Service: 31 | - lambda.amazonaws.com 32 | Policies: 33 | - PolicyName: "test-policy-name" 34 | PolicyDocument: 35 | Version: "2012-10-17" 36 | Statement: 37 | Action: 38 | - log:CreateLogStream 39 | Effect: Allow 40 | Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" 41 | Outputs: 42 | RoleName: 43 | Description: Role name 44 | Value: !Ref TestRole 45 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationTemplate/Tests/CloudFormationTemplates/TestUpdateTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test template for UpdateCloudFormationTemplate 20 | Resources: 21 | TestRole: 22 | Type: AWS::IAM::Role 23 | Properties: 24 | AssumeRolePolicyDocument: 25 | Version: "2012-10-17" 26 | Statement: 27 | - Action: ["sts:AssumeRole"] 28 | Effect: "Allow" 29 | Principal: 30 | Service: 31 | - lambda.amazonaws.com 32 | Policies: 33 | - PolicyName: "test-policy-name" 34 | PolicyDocument: 35 | Version: "2012-10-17" 36 | Statement: 37 | Action: 38 | - log:CreateLogStream 39 | - log:PutLogEvents 40 | - log:CreateLogGroup 41 | Effect: Allow 42 | Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" 43 | Outputs: 44 | RoleName: 45 | Description: Role name 46 | Value: !Ref TestRole 47 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Design/Design.md: -------------------------------------------------------------------------------- 1 | # Update CloudFormation Template 2 | 3 | ## Document Design 4 | 5 | Refer to schema.json 6 | 7 | ### Steps 8 | 9 | 1. aws:approve 10 | * Inputs: 11 | * NotificationArn: {{SNSTopicArn}} 12 | * Message: "Approval required to update CloudFormation stack: {{StackNameOrId}}" 13 | * MinRequiredApprovals: 1 14 | * Approvers: {{Approvers}} 15 | 2. aws:createStack - Execute CloudFormation Template to create lambda. 16 | * Inputs: 17 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 18 | * Parameters: 19 | * LambdaRole: {{LambdaAssumeRole}} - role assumed by lambda to update the CloudFormation Template. 20 | * LambdaName: UpdateCFTemplate-{{automation:EXECUTION_ID}} 21 | 3. aws:invokeLambdaFunction - Execute Lambda to update CloudFormationTemplate. 22 | * Inputs: 23 | * FunctionName: UpdateCFTemplate-{{automation:EXECUTION_ID}} - Lambda name to use 24 | * Payload: 25 | * StackName: {{StackName}} - Stack to update 26 | * TemplateLocation: {{TemplateLocation}} - Location of template (e.g. https://s3.amazonaws.com/example/updated.template) 27 | 4. aws:deleteStack - Delete CloudFormation Template. 28 | * Inputs: 29 | * StackName: {{DocumentStackName}} - Stack name or Unique ID 30 | 31 | ### CloudFormation Template 32 | 33 | Creates Lambda used by the SSM document to update the CloudFormation Template 34 | 35 | #### Resources 36 | 37 | * IAM Role - Role used by lambda (only created if non specified by user {{LambdaRoleArn}}) 38 | * Lambda - does the actual work to update the CloudFormation Template. 39 | 40 | ## Tests 41 | 42 | ### test_update_formation_template.py 43 | 44 | Tests updating cloudformation template at the lambda level. 45 | 46 | ### test_document.py 47 | 48 | Full SSM integration test. 49 | 50 | 1. Create a bucket for test in us-west-2 51 | 2. Deploy CloudFormation Template in us-east-1 52 | * Create IAM Role 53 | 3. Upload updated CloudFormation template to test bucket in us-west-2 54 | * Add another policy to the IAM Role. 55 | 4. Execute SSM document to update CloudFormation Template. 56 | 5. Send automation signal. 57 | 6. Validate document executed correctly. 58 | 7. Validate new policy was added to IAM Role. 59 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Design/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "CloudFormation Template Update - Manage updating CloudFormation Template from a S3 bucket.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "StackNameOrId": { 7 | "type": "String", 8 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be updated" 9 | }, 10 | "TemplateUrl": { 11 | "type": "String", 12 | "description": "(Required) S3 bucket location of updated CloudFormation Template (e.g. https://s3.amazonaws.com/example/updated.template)" 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "description": "(Required) The ARN of the role assumed by lambda" 17 | }, 18 | "Approvers": { 19 | "type": "StringList", 20 | "description": "(Required) IAM user or user arn of approvers for the automation action" 21 | }, 22 | "SNSTopicArn": { 23 | "type": "String", 24 | "description": "(Required) The SNS topic ARN used to send pending approval notification for updating CloudFormation Template. The SNS topic name must start with Automation." 25 | }, 26 | "AutomationAssumeRole": { 27 | "type": "String", 28 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 29 | "default": "" 30 | } 31 | }, 32 | "mainSteps": [] 33 | } -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Documents/CloudFormationTemplates/UpdateCFTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Parameters: 20 | LambdaRoleArn: 21 | Description: > 22 | The ARN of the role that allows Lambda created by Automation to perform the action on your behalf 23 | Type: String 24 | Default: "" 25 | LambdaName: 26 | Description: > 27 | The lambda function name 28 | Type: String 29 | Resources: 30 | UpdateCFLambda: 31 | Type: AWS::Lambda::Function 32 | Properties: 33 | Code: 34 | ZipFile: "{}" 35 | FunctionName: !Ref LambdaName 36 | Role: !Ref LambdaRoleArn 37 | Timeout: 60 38 | Handler: "index.handler" 39 | Runtime: python2.7 40 | MemorySize: 128 41 | 42 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Documents/Lambdas/update_cf_template.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | import boto3 18 | 19 | 20 | def handler(event, context): 21 | cf = boto3.client("cloudformation") 22 | 23 | cf.update_stack( 24 | StackName=event["StackName"], 25 | TemplateURL=event["TemplateUrl"], 26 | Capabilities=["CAPABILITY_IAM"] 27 | ) 28 | 29 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | TARGET_DIR = "./Output" 18 | 19 | documents: targetdir createdocuments 20 | @echo "Done making documents" 21 | 22 | targetdir: 23 | @echo "Making $(TARGET_DIR)" 24 | mkdir -p ./Output 25 | 26 | createdocuments: 27 | python ./Setup/create_document.py > ./Output/aws-UpdateCloudFormationWithApproval.json 28 | 29 | test: documents 30 | python -m unittest discover Tests 31 | 32 | clean: 33 | @echo "Removing $(TARGET_DIR)" 34 | @rm -rf ./Output 35 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Tests/CloudFormationTemplates/TestTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test template for UpdateCloudFormationTemplate 20 | Resources: 21 | TestRole: 22 | Type: AWS::IAM::Role 23 | Properties: 24 | AssumeRolePolicyDocument: 25 | Version: "2012-10-17" 26 | Statement: 27 | - Action: ["sts:AssumeRole"] 28 | Effect: "Allow" 29 | Principal: 30 | Service: 31 | - lambda.amazonaws.com 32 | Policies: 33 | - PolicyName: "test-policy-name" 34 | PolicyDocument: 35 | Version: "2012-10-17" 36 | Statement: 37 | Action: 38 | - log:CreateLogStream 39 | Effect: Allow 40 | Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" 41 | Outputs: 42 | RoleName: 43 | Description: Role name 44 | Value: !Ref TestRole 45 | -------------------------------------------------------------------------------- /Documents/Automation/UpdateCloudFormationWithApproval/Tests/CloudFormationTemplates/TestUpdateTemplate.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | # software and associated documentation files (the "Software"), to deal in the Software 6 | # without restriction, including without limitation the rights to use, copy, modify, 7 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | # permit persons to whom the Software is furnished to do so. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | --- 18 | AWSTemplateFormatVersion: '2010-09-09' 19 | Description: Test template for UpdateCloudFormationTemplate 20 | Resources: 21 | TestRole: 22 | Type: AWS::IAM::Role 23 | Properties: 24 | AssumeRolePolicyDocument: 25 | Version: "2012-10-17" 26 | Statement: 27 | - Action: ["sts:AssumeRole"] 28 | Effect: "Allow" 29 | Principal: 30 | Service: 31 | - lambda.amazonaws.com 32 | Policies: 33 | - PolicyName: "test-policy-name" 34 | PolicyDocument: 35 | Version: "2012-10-17" 36 | Statement: 37 | Action: 38 | - log:CreateLogStream 39 | - log:PutLogEvents 40 | - log:CreateLogGroup 41 | Effect: Allow 42 | Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" 43 | Outputs: 44 | RoleName: 45 | Description: Role name 46 | Value: !Ref TestRole 47 | -------------------------------------------------------------------------------- /Documents/Automation/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | demjson 3 | PyYAML 4 | mock 5 | -------------------------------------------------------------------------------- /Documents/Command/ConfigureAgentLogsUploadToCloudwatch/README.md: -------------------------------------------------------------------------------- 1 | # Configure SSM Agent CloudWatch Logging 2 | 3 | This is a Systems Manager Document to configure SSM Agent logging to CloudWatch Logs. The document updates the logging configuration file. It can be used to change log level or add CloudWatch Logs as a logging destination. By enabling CloudWatch upload, all logs of SSM Agent would also be streamed to the CloudWatch instance in addition to the being added to the log file on disk. 4 | 5 | ## Type of Document 6 | 7 | *Command* Document - Can be used with Run Command 8 | 9 | ## Supported Platforms 10 | 11 | Supported for *Windows*, *Linux* 12 | 13 | ## Supported SSM Agent Versions 14 | 15 | Agent Version 2.0.902.0 and above 16 | 17 | ## Parameters 18 | 19 | ### LogLevel 20 | 21 | Specify the Log Level of SSM Agent logs. This would change the log level for all logging destinations specified (file/console/cloudwatch/others) 22 | 23 | ### EnableCloudWatchUpload 24 | 25 | On setting this to true, SSM Agent will start logging to CloudWatchLogs of the AWS Account and in the region it is running. Setting it to false will disable the logging to CloudWatchLogs. 26 | 27 | ### LogGroup 28 | 29 | (Optional) Specify the log group name for logging in CloudWatchLogs. The log group would be created if not already present. If not specified, the logs would be present in the default log group 'SSMAgentLogs'. 30 | 31 | ## Details 32 | 33 | Executing the document will update the seelog.xml file used by SSM agent with the configurations being passed as parameters. The Agent will pick the latest logging configurations and depending on the parameters may: 34 | - Change the log level of SSM Agent 35 | - Enable/Disable logging to CloudWatchLogs 36 | 37 | ## Dependencies 38 | For Linux, the XML modification would install XMLStarlet command line utility (under MIT license) if not already installed. 39 | 40 | -------------------------------------------------------------------------------- /Documents/Command/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder file to be taken out once contribution has been made to this directory. 2 | -------------------------------------------------------------------------------- /Inventory/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-systems-manager/81deddae6d864f2e236346c880f88b7905ec549a/Inventory/README.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | software and associated documentation files (the "Software"), to deal in the Software 5 | without restriction, including without limitation the rights to use, copy, modify, 6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 10 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 11 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 12 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 13 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Amazon-SSM 2 | Copyright 2018-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Systems Manager 2 | Welcome to the Systems Manager community! Systems Manager allows you to automate common administrative tasks across resources on AWS and on-premises. Using Systems Manager, you can group resources by application and automate operational tasks on those resources. For example, you can remotely manage, collect inventory, patch, and configure your grouped resources. 3 | 4 | ## New to Systems Manager? 5 | Here are some resources for you to get started with Systems Manager: 6 | 7 | * [Getting Started](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) documentation 8 | * Blogposts on the [AWS Blog](https://aws.amazon.com/blogs/aws/category/management-tools/amazon-ec2-systems-manager/) and the [AWS Management Tools Blog](https://aws.amazon.com/blogs/mt/category/management-tools/amazon-ec2-systems-manager/) 9 | * The SSM Agent is also open sourced on GitHub [here](https://github.com/aws/amazon-ssm-agent) 10 | 11 | ## Structure 12 | The repository has top level folders that include: 13 | 14 | * Documents: Contains Automation and Command type Documents. Each Document is a separate folder under the respective Document type 15 | * Compliance: Contains InSpec profiles and other compliance scripts that you can use with Systems Manager 16 | * Inventory: Contains custom gatherers that you can use with the Inventory service 17 | * Examples: Any artifact that does not fit into the other categories will be a separate folder for that artifact 18 | 19 | ## Developing and Contributing 20 | Contributions are welcome! The goal of the project is for developers to provide artifacts, documentation, and examples of product usage to share with the community. 21 | 22 | Please see the [CONTRIBUTING.md](https://github.com/awslabs/amazon-ssm/blob/master/CONTRIBUTING.md) file for more information. 23 | 24 | ## Legal and Licensing 25 | This repository is licensed under the [MIT no attribution license](https://github.com/awslabs/amazon-ssm/blob/master/LICENSE). 26 | --------------------------------------------------------------------------------