├── README.md ├── documents ├── AWS-ASGEnterStandby ├── AWS-ASGExitStandby ├── AWS-ApplyDSCMofs ├── AWS-ApplyPatchBaseline ├── AWS-AttachEBSVolume ├── AWS-AttachIAMToInstance ├── AWS-ConfigureAWSPackage ├── AWS-ConfigureCloudWatch ├── AWS-ConfigureCloudWatchOnEC2Instance ├── AWS-ConfigureDocker ├── AWS-ConfigureS3BucketLogging ├── AWS-ConfigureS3BucketVersioning ├── AWS-ConfigureWindowsUpdate ├── AWS-CopySnapshot ├── AWS-CreateDynamoDbBackup ├── AWS-CreateImage ├── AWS-CreateJiraIssue ├── AWS-CreateManagedLinuxInstance ├── AWS-CreateManagedLinuxInstanceWithApproval ├── AWS-CreateManagedWindowsInstance ├── AWS-CreateManagedWindowsInstanceWithApproval ├── AWS-CreateSnapshot ├── AWS-DeleteCloudFormationStack ├── AWS-DeleteCloudFormationStackWithApproval ├── AWS-DeleteDynamoDbBackup ├── AWS-DeleteDynamoDbTableBackups ├── AWS-DeleteEbsVolumeSnapshots ├── AWS-DeleteImage ├── AWS-DeleteSnapshot ├── AWS-DetachEBSVolume ├── AWS-DisablePublicAccessForSecurityGroup ├── AWS-DisableS3BucketPublicReadWrite ├── AWS-EnableCloudTrail ├── AWS-EnableS3BucketEncryption ├── AWS-FindWindowsUpdates ├── AWS-GatherSoftwareInventory ├── AWS-InstallApplication ├── AWS-InstallMissingWindowsUpdates ├── AWS-InstallPowerShellModule ├── AWS-InstallSpecificWindowsUpdates ├── AWS-InstallWindowsUpdates ├── AWS-JoinDirectoryServiceDomain ├── AWS-ListWindowsInventory ├── AWS-PasswordReset ├── AWS-PatchAsgInstance ├── AWS-PatchInstanceWithRollback ├── AWS-PublishSNSNotification ├── AWS-RebootRdsInstance ├── AWS-RefreshAssociation ├── AWS-ReleaseElasticIP ├── AWS-ResizeInstance ├── AWS-RestartEC2Instance ├── AWS-RestartEC2InstanceWithApproval ├── AWS-RunAnsiblePlaybook ├── AWS-RunDockerAction ├── AWS-RunDocument ├── AWS-RunInspecChecks ├── AWS-RunPatchBaseline ├── AWS-RunPowerShellScript ├── AWS-RunRemoteScript ├── AWS-RunSaltState ├── AWS-RunShellScript ├── AWS-SetupInventory ├── AWS-SetupManagedInstance ├── AWS-SetupManagedRoleOnEc2Instance ├── AWS-StartEC2Instance ├── AWS-StartEC2InstanceWithApproval ├── AWS-StartPortForwardingSession ├── AWS-StartRdsInstance ├── AWS-StartSSHSession ├── AWS-StopEC2Instance ├── AWS-StopEC2InstanceWithApproval ├── AWS-StopRdsInstance ├── AWS-TerminateEC2Instance ├── AWS-TerminateEC2InstanceWithApproval ├── AWS-UpdateCloudFormationStack ├── AWS-UpdateCloudFormationStackWithApproval ├── AWS-UpdateEC2Config ├── AWS-UpdateLinuxAmi ├── AWS-UpdateSSMAgent ├── AWS-UpdateWindowsAmi ├── AWSEC2-ApplicationInsightsCloudwatchAgentInstallAndConfigure ├── AWSEC2-CloneInstanceAndUpgradeSQLServer ├── AWSEC2-CloneInstanceAndUpgradeWindows ├── AWSEC2-CreateVssSnapshot ├── AWSEC2-ManageVssIO ├── AWSEC2-RunSysprep ├── AWSEC2-SQLServerDBRestore ├── AWSSupport-ActivateWindowsWithAmazonLicense ├── AWSSupport-ExecuteEC2Rescue ├── AWSSupport-GrantPermissionsToIAMUser ├── AWSSupport-ManageRDPSettings ├── AWSSupport-ManageWindowsService ├── AWSSupport-ResetAccess ├── AWSSupport-RunEC2RescueForWindowsTool ├── AWSSupport-SendLogBundleToS3Bucket ├── AWSSupport-SetupIPMonitoringFromVPC ├── AWSSupport-StartEC2RescueWorkflow ├── AWSSupport-TerminateIPMonitoringFromVPC ├── AWSSupport-TroubleshootRDP ├── AWSSupport-TroubleshootSSH ├── AWSSupport-UpgradeWindowsAWSDrivers ├── AmazonCloudWatch-ManageAgent ├── AmazonCloudWatch-MigrateCloudWatchAgent └── AmazonInspector-ManageAWSAgent └── list-documents.json /README.md: -------------------------------------------------------------------------------- 1 | Collection of the AWS SSM documents. These were acquired as follows: 2 | 3 | ``` 4 | aws ssm list-documents > list-documents.json 5 | cat list-documents.json | jq -cr '.DocumentIdentifiers[].Name' | xargs -n1 sh -c 'aws ssm get-document --name $1 | jq ".Content|fromjson" > "documents/$1"' sh 6 | ``` 7 | 8 | This formats the double-encoded json document to prettified single json. 9 | -------------------------------------------------------------------------------- /documents/AWS-ASGEnterStandby: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Change the Standby state of an EC2 instance in an autoscaling group", 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 | "action": "aws:createStack", 24 | "inputs": { 25 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}", 26 | "Parameters": [ 27 | { 28 | "ParameterValue": "asg-state-change-lambda-{{automation:EXECUTION_ID}}", 29 | "ParameterKey": "FunctionName" 30 | }, 31 | { 32 | "ParameterValue": "{{LambdaRoleArn}}", 33 | "ParameterKey": "LambdaRoleArn" 34 | } 35 | ], 36 | "Capabilities": [ 37 | "CAPABILITY_IAM" 38 | ], 39 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n IsVerbose:\n Fn::Equals:\n - {Ref: Verbose}\n - 'true'\n IsVerboseAndLambdaRoleNotSpecified:\n Fn::And:\n - {Condition: LambdaAssumeRoleNotSpecified}\n - {Condition: IsVerbose}\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nDescription: Automation stack for ASG Change Standby state documents\nParameters:\n FunctionName: {Description: What to name the deployed lambda function, Type: String}\n LambdaRoleArn: {Default: '', Description: 'Assume role used by the lambda function.\n If not specified this template will create a temporary role to be used by the\n lambda created in this template.\n\n ', Type: String}\n Verbose:\n AllowedValues: ['true', 'false']\n Default: 'true'\n Description: 'Verbose setting\n\n '\n Type: String\nResources:\n ChangeASGStateLambda:\n Properties:\n Code: {ZipFile: \"import logging\\n\\nimport boto3\\n\\n\\ndef handler(event, context):\\n\\\n \\t\\\"\\\"\\\"\\n\\tChanges the state of an instance in an autoscaling group. The\\\n \\ IAM role running this lambda requires the following\\n\\tpermissions:\\n\\t\\\n {\\n\\t \\\"Effect\\\": \\\"Allow\\\",\\n\\t \\\"Action\\\": [\\n\\t\\t\\\"autoscaling:EnterStandby\\\"\\\n ,\\n\\t\\t\\\"autoscaling:ExitStandby\\\",\\n\\t\\t\\\"autoscaling:DescribeAutoScalingInstances\\n\\\n \\t ],\\n\\t \\\"Resource\\\": \\\"*\\\"\\n\\t}\\n\\t:param event: Defined fields:\\n\\t\\\n \\t{\\n\\t\\t \\\"State\\\": \\\"EnterStandby|ExitStandby\\\",\\n\\t\\t \\\"InstanceId\\\"\\\n : \\\"i-1234567890\\\",\\n\\t\\t \\\"ASGName\\\": \\\"MyASGName\\\",\\n\\t\\t \\\"ShouldDecrement\\\"\\\n : true|false\\n\\t\\t}\\n\\tThe ShouldDecrement field is only used for EnterStandby\\\n \\ and ignored otherwise\\n\\t\\\"\\\"\\\"\\n\\tas_client = boto3.client('autoscaling')\\n\\\n \\t# The state to transition to. Options are EnterStandby and ExitStandby\\n\\\n \\tstate = event.get('State')\\n\\tinstance_id = event.get('InstanceId')\\n\\t\\\n decrement = event.get('ShouldDecrement', False)\\n\\n\\tassert state in {'EnterStandby',\\\n \\ 'ExitStandby'}, 'Invalid state provided'\\n\\tassert instance_id is not\\\n \\ None, 'InstanceId must be specified'\\n\\n\\tinstances = as_client.describe_auto_scaling_instances(InstanceIds=[instance_id])\\n\\\n \\tif len(instances.get(\\\"AutoScalingInstances\\\", [])) > 0:\\n\\t\\tasg_name\\\n \\ = instances[\\\"AutoScalingInstances\\\"][0][\\\"AutoScalingGroupName\\\"]\\n\\t\\\n \\tif state == 'EnterStandby':\\n\\t\\t\\tprint \\\"Enter Standby: {} {}\\\".format(instance_id,\\\n \\ asg_name)\\n\\t\\t\\tas_client.enter_standby(InstanceIds=[instance_id],\\n\\t\\\n \\t\\t\\t\\t\\t\\t\\t\\tAutoScalingGroupName=asg_name,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tShouldDecrementDesiredCapacity=decrement)\\n\\\n \\t\\telse:\\n\\t\\t\\tprint \\\"Exit Standby: {} {}\\\".format(instance_id, asg_name)\\n\\\n \\t\\t\\tas_client.exit_standby(InstanceIds=[instance_id], AutoScalingGroupName=asg_name)\\n\"}\n FunctionName: {Ref: FunctionName}\n Handler: index.handler\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Type: AWS::Lambda::Function\n LambdaLogPolicy:\n Condition: IsVerboseAndLambdaRoleNotSpecified\n Properties:\n PolicyDocument:\n Statement:\n Action: ['log:CreateLogStream', 'log:PutLogEvents', 'log:CreateLogGroup']\n Effect: Allow\n Resource: {'Fn::Sub': 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'}\n Version: '2012-10-17'\n PolicyName: lambda-log-access\n Roles:\n - {Ref: LambdaRole}\n Type: AWS::IAM::Policy\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['autoscaling:EnterStandby', 'autoscaling:ExitStandby', 'autoscaling:DescribeAutoScalingInstances']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: asg-access\n Type: AWS::IAM::Role\n" 40 | }, 41 | "maxAttempts": 1, 42 | "name": "deployChangeStateLambda", 43 | "onFailure": "Abort" 44 | }, 45 | { 46 | "action": "aws:invokeLambdaFunction", 47 | "inputs": { 48 | "FunctionName": "asg-state-change-lambda-{{automation:EXECUTION_ID}}", 49 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"State\": \"EnterStandby\", \"ShouldDecrement\": true}" 50 | }, 51 | "maxAttempts": 1, 52 | "name": "changeState", 53 | "onFailure": "Abort" 54 | }, 55 | { 56 | "action": "aws:deleteStack", 57 | "inputs": { 58 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}" 59 | }, 60 | "maxAttempts": 1, 61 | "name": "deleteChangeStateLambda", 62 | "onFailure": "Abort" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /documents/AWS-ASGExitStandby: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Change the Standby state of an EC2 instance in an autoscaling group", 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 | "action": "aws:createStack", 24 | "inputs": { 25 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}", 26 | "Parameters": [ 27 | { 28 | "ParameterValue": "asg-state-change-lambda-{{automation:EXECUTION_ID}}", 29 | "ParameterKey": "FunctionName" 30 | }, 31 | { 32 | "ParameterValue": "{{LambdaRoleArn}}", 33 | "ParameterKey": "LambdaRoleArn" 34 | } 35 | ], 36 | "Capabilities": [ 37 | "CAPABILITY_IAM" 38 | ], 39 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n IsVerbose:\n Fn::Equals:\n - {Ref: Verbose}\n - 'true'\n IsVerboseAndLambdaRoleNotSpecified:\n Fn::And:\n - {Condition: LambdaAssumeRoleNotSpecified}\n - {Condition: IsVerbose}\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nDescription: Automation stack for ASG Change Standby state documents\nParameters:\n FunctionName: {Description: What to name the deployed lambda function, Type: String}\n LambdaRoleArn: {Default: '', Description: 'Assume role used by the lambda function.\n If not specified this template will create a temporary role to be used by the\n lambda created in this template.\n\n ', Type: String}\n Verbose:\n AllowedValues: ['true', 'false']\n Default: 'true'\n Description: 'Verbose setting\n\n '\n Type: String\nResources:\n ChangeASGStateLambda:\n Properties:\n Code: {ZipFile: \"import logging\\n\\nimport boto3\\n\\n\\ndef handler(event, context):\\n\\\n \\t\\\"\\\"\\\"\\n\\tChanges the state of an instance in an autoscaling group. The\\\n \\ IAM role running this lambda requires the following\\n\\tpermissions:\\n\\t\\\n {\\n\\t \\\"Effect\\\": \\\"Allow\\\",\\n\\t \\\"Action\\\": [\\n\\t\\t\\\"autoscaling:EnterStandby\\\"\\\n ,\\n\\t\\t\\\"autoscaling:ExitStandby\\\",\\n\\t\\t\\\"autoscaling:DescribeAutoScalingInstances\\n\\\n \\t ],\\n\\t \\\"Resource\\\": \\\"*\\\"\\n\\t}\\n\\t:param event: Defined fields:\\n\\t\\\n \\t{\\n\\t\\t \\\"State\\\": \\\"EnterStandby|ExitStandby\\\",\\n\\t\\t \\\"InstanceId\\\"\\\n : \\\"i-1234567890\\\",\\n\\t\\t \\\"ASGName\\\": \\\"MyASGName\\\",\\n\\t\\t \\\"ShouldDecrement\\\"\\\n : true|false\\n\\t\\t}\\n\\tThe ShouldDecrement field is only used for EnterStandby\\\n \\ and ignored otherwise\\n\\t\\\"\\\"\\\"\\n\\tas_client = boto3.client('autoscaling')\\n\\\n \\t# The state to transition to. Options are EnterStandby and ExitStandby\\n\\\n \\tstate = event.get('State')\\n\\tinstance_id = event.get('InstanceId')\\n\\t\\\n decrement = event.get('ShouldDecrement', False)\\n\\n\\tassert state in {'EnterStandby',\\\n \\ 'ExitStandby'}, 'Invalid state provided'\\n\\tassert instance_id is not\\\n \\ None, 'InstanceId must be specified'\\n\\n\\tinstances = as_client.describe_auto_scaling_instances(InstanceIds=[instance_id])\\n\\\n \\tif len(instances.get(\\\"AutoScalingInstances\\\", [])) > 0:\\n\\t\\tasg_name\\\n \\ = instances[\\\"AutoScalingInstances\\\"][0][\\\"AutoScalingGroupName\\\"]\\n\\t\\\n \\tif state == 'EnterStandby':\\n\\t\\t\\tprint \\\"Enter Standby: {} {}\\\".format(instance_id,\\\n \\ asg_name)\\n\\t\\t\\tas_client.enter_standby(InstanceIds=[instance_id],\\n\\t\\\n \\t\\t\\t\\t\\t\\t\\t\\tAutoScalingGroupName=asg_name,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tShouldDecrementDesiredCapacity=decrement)\\n\\\n \\t\\telse:\\n\\t\\t\\tprint \\\"Exit Standby: {} {}\\\".format(instance_id, asg_name)\\n\\\n \\t\\t\\tas_client.exit_standby(InstanceIds=[instance_id], AutoScalingGroupName=asg_name)\\n\"}\n FunctionName: {Ref: FunctionName}\n Handler: index.handler\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Type: AWS::Lambda::Function\n LambdaLogPolicy:\n Condition: IsVerboseAndLambdaRoleNotSpecified\n Properties:\n PolicyDocument:\n Statement:\n Action: ['log:CreateLogStream', 'log:PutLogEvents', 'log:CreateLogGroup']\n Effect: Allow\n Resource: {'Fn::Sub': 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'}\n Version: '2012-10-17'\n PolicyName: lambda-log-access\n Roles:\n - {Ref: LambdaRole}\n Type: AWS::IAM::Policy\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['autoscaling:EnterStandby', 'autoscaling:ExitStandby', 'autoscaling:DescribeAutoScalingInstances']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: asg-access\n Type: AWS::IAM::Role\n" 40 | }, 41 | "maxAttempts": 1, 42 | "name": "deployChangeStateLambda", 43 | "onFailure": "Abort" 44 | }, 45 | { 46 | "action": "aws:invokeLambdaFunction", 47 | "inputs": { 48 | "FunctionName": "asg-state-change-lambda-{{automation:EXECUTION_ID}}", 49 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"State\": \"ExitStandby\"}" 50 | }, 51 | "maxAttempts": 1, 52 | "name": "changeState", 53 | "onFailure": "Abort" 54 | }, 55 | { 56 | "action": "aws:deleteStack", 57 | "inputs": { 58 | "StackName": "asg-state-change-lambda-cfn-stack-{{automation:EXECUTION_ID}}" 59 | }, 60 | "maxAttempts": 1, 61 | "name": "deleteChangeStateLambda", 62 | "onFailure": "Abort" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /documents/AWS-AttachEBSVolume: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{ AutomationAssumeRole }}", 4 | "description": "Attach EBS Volume", 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 | "default": "", 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. " 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "action": "aws:createStack", 27 | "inputs": { 28 | "StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}", 29 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nDescription: Template to attach a EBS volume to an EC2 Instance\nParameters:\n Device: {Description: 'The device name (for example, /dev/sdh or xvdh )\n\n ', Type: String}\n InstanceId: {Description: 'The ID of the instance\n\n ', Type: String}\n VolumeId: {Description: 'The ID of the EBS volume. The volume and instance must\n be within the same Availability Zone\n\n ', Type: String}\nResources:\n TestResource:\n DeletionPolicy: Retain\n Properties:\n Device: {Ref: Device}\n InstanceId: {Ref: InstanceId}\n VolumeId: {Ref: VolumeId}\n Type: AWS::EC2::VolumeAttachment\n", 30 | "Parameters": [ 31 | { 32 | "ParameterValue": "{{Device}}", 33 | "ParameterKey": "Device" 34 | }, 35 | { 36 | "ParameterValue": "{{InstanceId}}", 37 | "ParameterKey": "InstanceId" 38 | }, 39 | { 40 | "ParameterValue": "{{VolumeId}}", 41 | "ParameterKey": "VolumeId" 42 | } 43 | ], 44 | "Capabilities": [ 45 | "CAPABILITY_IAM" 46 | ] 47 | }, 48 | "name": "createDocumentStack" 49 | }, 50 | { 51 | "action": "aws:deleteStack", 52 | "inputs": { 53 | "StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}" 54 | }, 55 | "name": "deleteCloudFormationTemplate" 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /documents/AWS-AttachIAMToInstance: -------------------------------------------------------------------------------- 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 | "ForceReplace": { 15 | "type": "Boolean", 16 | "description": "(Optional) Flag to specify whether to replace the existing iam profile or not.", 17 | "default": true 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": "DescribeInstanceProfile", 28 | "action": "aws:executeAwsApi", 29 | "onFailure": "Abort", 30 | "inputs": { 31 | "Service": "ec2", 32 | "Api": "describe_iam_instance_profile_associations", 33 | "Filters": [ 34 | { 35 | "Name": "instance-id", 36 | "Values": [ 37 | "{{InstanceId}}" 38 | ] 39 | } 40 | ] 41 | }, 42 | "outputs": [ 43 | { 44 | "Name": "InstanceProfileArn", 45 | "Selector": "$.IamInstanceProfileAssociations[0].IamInstanceProfile.Arn", 46 | "Type": "String" 47 | }, 48 | { 49 | "Name": "AssociationId", 50 | "Selector": "$.IamInstanceProfileAssociations[0].AssociationId", 51 | "Type": "String" 52 | } 53 | ] 54 | }, 55 | { 56 | "name": "CheckInstanceProfileAssociations", 57 | "action": "aws:branch", 58 | "inputs": { 59 | "Choices": [ 60 | { 61 | "NextStep": "ListInstanceProfilesForRole", 62 | "Not": { 63 | "Variable": "{{DescribeInstanceProfile.InstanceProfileArn}}", 64 | "Contains": "arn:" 65 | } 66 | }, 67 | { 68 | "NextStep": "DisassociateIamInstanceProfile", 69 | "Variable": "{{ForceReplace}}", 70 | "BooleanEquals": true 71 | } 72 | ] 73 | }, 74 | "isEnd": true 75 | }, 76 | { 77 | "name": "DisassociateIamInstanceProfile", 78 | "action": "aws:executeAwsApi", 79 | "onFailure": "Abort", 80 | "inputs": { 81 | "Service": "ec2", 82 | "Api": "disassociate_iam_instance_profile", 83 | "AssociationId": "{{DescribeInstanceProfile.AssociationId}}" 84 | } 85 | }, 86 | { 87 | "name": "ListInstanceProfilesForRole", 88 | "action": "aws:executeAwsApi", 89 | "onFailure": "Abort", 90 | "inputs": { 91 | "Service": "iam", 92 | "Api": "list_instance_profiles_for_role", 93 | "RoleName": "{{RoleName}}" 94 | }, 95 | "outputs": [ 96 | { 97 | "Name": "InstanceProfileArn", 98 | "Selector": "$.InstanceProfiles[0].Arn", 99 | "Type": "String" 100 | }, 101 | { 102 | "Name": "InstanceProfileName", 103 | "Selector": "$.InstanceProfiles[0].InstanceProfileName", 104 | "Type": "String" 105 | } 106 | ] 107 | }, 108 | { 109 | "name": "CheckInstanceProfileCreated", 110 | "action": "aws:branch", 111 | "inputs": { 112 | "Choices": [ 113 | { 114 | "NextStep": "CreateInstanceProfileForRole", 115 | "Not": { 116 | "Variable": "{{ListInstanceProfilesForRole.InstanceProfileArn}}", 117 | "Contains": "arn:" 118 | } 119 | } 120 | ], 121 | "Default": "AttachIAMProfileToInstance" 122 | } 123 | }, 124 | { 125 | "name": "AttachIAMProfileToInstance", 126 | "action": "aws:executeAwsApi", 127 | "onFailure": "Abort", 128 | "inputs": { 129 | "Service": "ec2", 130 | "Api": "associate_iam_instance_profile", 131 | "InstanceId": "{{InstanceId}}", 132 | "IamInstanceProfile": { 133 | "Arn": "{{ListInstanceProfilesForRole.InstanceProfileArn}}", 134 | "Name": "{{ListInstanceProfilesForRole.InstanceProfileName}}" 135 | } 136 | }, 137 | "isEnd": true, 138 | "outputs": [ 139 | { 140 | "Name": "AssociationId", 141 | "Selector": "$.IamInstanceProfileAssociation.AssociationId", 142 | "Type": "String" 143 | } 144 | ] 145 | }, 146 | { 147 | "name": "CreateInstanceProfileForRole", 148 | "action": "aws:executeAwsApi", 149 | "onFailure": "Abort", 150 | "inputs": { 151 | "Service": "iam", 152 | "Api": "create_instance_profile", 153 | "InstanceProfileName": "{{RoleName}}", 154 | "Path": "/" 155 | } 156 | }, 157 | { 158 | "name": "AddRoleToInstanceProfile", 159 | "action": "aws:executeAwsApi", 160 | "onFailure": "Abort", 161 | "inputs": { 162 | "Service": "iam", 163 | "Api": "add_role_to_instance_profile", 164 | "InstanceProfileName": "{{RoleName}}", 165 | "RoleName": "{{RoleName}}" 166 | } 167 | }, 168 | { 169 | "name": "GetInstanceProfile", 170 | "action": "aws:executeAwsApi", 171 | "onFailure": "Abort", 172 | "inputs": { 173 | "Service": "iam", 174 | "Api": "get_instance_profile", 175 | "InstanceProfileName": "{{RoleName}}" 176 | }, 177 | "outputs": [ 178 | { 179 | "Name": "InstanceProfileArn", 180 | "Selector": "$.InstanceProfile.Arn", 181 | "Type": "String" 182 | }, 183 | { 184 | "Name": "InstanceProfileName", 185 | "Selector": "$.InstanceProfile.InstanceProfileName", 186 | "Type": "String" 187 | } 188 | ] 189 | }, 190 | { 191 | "name": "AttachIAMProfileToInstanceWithRetry", 192 | "action": "aws:executeAwsApi", 193 | "onFailure": "Abort", 194 | "maxAttempts": 20, 195 | "timeoutSeconds": 2, 196 | "inputs": { 197 | "Service": "ec2", 198 | "Api": "associate_iam_instance_profile", 199 | "InstanceId": "{{InstanceId}}", 200 | "IamInstanceProfile": { 201 | "Arn": "{{GetInstanceProfile.InstanceProfileArn}}", 202 | "Name": "{{GetInstanceProfile.InstanceProfileName}}" 203 | } 204 | }, 205 | "isEnd": true, 206 | "outputs": [ 207 | { 208 | "Name": "AssociationId", 209 | "Selector": "$.IamInstanceProfileAssociation.AssociationId", 210 | "Type": "String" 211 | } 212 | ] 213 | } 214 | ], 215 | "outputs": [ 216 | "AttachIAMProfileToInstanceWithRetry.AssociationId", 217 | "GetInstanceProfile.InstanceProfileName", 218 | "GetInstanceProfile.InstanceProfileArn", 219 | "AttachIAMProfileToInstance.AssociationId", 220 | "ListInstanceProfilesForRole.InstanceProfileName", 221 | "ListInstanceProfilesForRole.InstanceProfileArn" 222 | ] 223 | } 224 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureAWSPackage: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Install or uninstall the latest version or specified version of a package. For example, some standard packages are AwsEnaNetworkDriver, AWSPVDriver, and IntelSriovDriver.", 4 | "parameters": { 5 | "action": { 6 | "description": "(Required) Specify whether or not to install or uninstall the package.", 7 | "type": "String", 8 | "allowedValues": [ 9 | "Install", 10 | "Uninstall" 11 | ] 12 | }, 13 | "name": { 14 | "description": "(Required) The package to install/uninstall.", 15 | "type": "String", 16 | "allowedPattern": "^arn:[a-z0-9][-.a-z0-9]{0,62}:[a-z0-9][-.a-z0-9]{0,62}:([a-z0-9][-.a-z0-9]{0,62})?:([a-z0-9][-.a-z0-9]{0,62})?:(package|document)\\/[a-zA-Z0-9/:.\\-_]{1,128}$|^[a-zA-Z0-9/:.\\-_]{1,128}$" 17 | }, 18 | "version": { 19 | "description": "(Optional) A specific version of the package to install or uninstall. If installing, the system installs the latest published version, by default. If uninstalling, the system uninstalls the currently installed version, by default. If no installed version is found, the latest published version is downloaded, and the uninstall action is run.", 20 | "type": "String", 21 | "default": "" 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "action": "aws:configurePackage", 27 | "name": "configurePackage", 28 | "inputs": { 29 | "name": "{{ name }}", 30 | "action": "{{ action }}", 31 | "version": "{{ version }}" 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureCloudWatch: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Export metrics and log files from your instances to Amazon CloudWatch.", 4 | "parameters": { 5 | "status": { 6 | "type": "String", 7 | "default": "Enabled", 8 | "description": "(Optional) Enable or disable CloudWatch. Valid values: Enabled | Disabled", 9 | "allowedValues": [ 10 | "Enabled", 11 | "Disabled" 12 | ] 13 | }, 14 | "properties": { 15 | "type": "String", 16 | "default": "", 17 | "description": "(Optional) The configuration for CloudWatch in JSON format. Learn more at https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-plugins.html#aws-cloudWatch", 18 | "displayType": "textarea" 19 | } 20 | }, 21 | "runtimeConfig": { 22 | "aws:cloudWatch": { 23 | "settings": { 24 | "startType": "{{ status }}" 25 | }, 26 | "properties": "{{ properties }}" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureCloudWatchOnEC2Instance: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Configure CloudWatch on Instance", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) InstanceId of the EC2 instance to configure" 9 | }, 10 | "status": { 11 | "default": "Enabled", 12 | "type": "String", 13 | "description": "(Optional) Specifies whether to enable or disable CloudWatch. Valid values: \"Enabled\" | \"Disabled\"", 14 | "allowedValues": [ 15 | "Enabled", 16 | "Disabled" 17 | ] 18 | }, 19 | "AutomationAssumeRole": { 20 | "default": "", 21 | "type": "String", 22 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf." 23 | }, 24 | "properties": { 25 | "default": "", 26 | "type": "String", 27 | "description": "(Optional) The configuration for CloudWatch in JSON format." 28 | }, 29 | "LambdaAssumeRole": { 30 | "default": "", 31 | "type": "String", 32 | "description": "(Optional) The ARN of the role assumed by lambda" 33 | } 34 | }, 35 | "mainSteps": [ 36 | { 37 | "action": "aws:createStack", 38 | "inputs": { 39 | "StackName": "ConfigureCloudWatchOnInstanceStack{{automation:EXECUTION_ID}}", 40 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nDescription: Automation Stack for Configure CloudWatch on EC2 Instance\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\nResources:\n ConfigureCloudWatchOnEC2InstanceLambda:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\n\\n\\ndef handler(event,\\\n \\ context):\\n\\tec2_client = boto3.client('ec2')\\n\\tinstance_id = event[\\\"\\\n InstanceId\\\"]\\n\\tnew_state = event[\\\"status\\\"] or \\\"Enabled\\\"\\n\\n\\tif new_state\\\n \\ == \\\"Enabled\\\":\\n\\t\\tec2_client.monitor_instances(InstanceIds=[instance_id])\\n\\\n \\tif new_state == \\\"Disabled\\\":\\n\\t\\tec2_client.unmonitor_instances(InstanceIds=[instance_id])\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['ec2:MonitorInstances', 'ec2:UnmonitorInstances']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: ConfigureCloudWatchOnEC2InstanceLambdaPolicy\n Type: AWS::IAM::Role\n", 41 | "Parameters": [ 42 | { 43 | "ParameterValue": "{{LambdaAssumeRole}}", 44 | "ParameterKey": "LambdaRoleArn" 45 | }, 46 | { 47 | "ParameterValue": "CfgCwOnEc2InstanceLambda-{{automation:EXECUTION_ID}}", 48 | "ParameterKey": "LambdaName" 49 | } 50 | ], 51 | "Capabilities": [ 52 | "CAPABILITY_IAM" 53 | ] 54 | }, 55 | "name": "createDocumentStack" 56 | }, 57 | { 58 | "action": "aws:invokeLambdaFunction", 59 | "inputs": { 60 | "FunctionName": "CfgCwOnEc2InstanceLambda-{{automation:EXECUTION_ID}}", 61 | "Payload": "{\"InstanceId\": \"{{InstanceId}}\", \"status\": \"{{status}}\" }" 62 | }, 63 | "name": "configureCloudWatchOnInstance" 64 | }, 65 | { 66 | "action": "aws:deleteStack", 67 | "inputs": { 68 | "StackName": "ConfigureCloudWatchOnInstanceStack{{automation:EXECUTION_ID}}" 69 | }, 70 | "name": "deleteCloudFormationTemplate" 71 | } 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureDocker: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Configure an instance to work with containers and Docker", 4 | "parameters": { 5 | "action": { 6 | "type": "String", 7 | "description": "The type of action to perform.", 8 | "allowedValues": [ 9 | "Install", 10 | "Uninstall" 11 | ] 12 | } 13 | }, 14 | "mainSteps": [ 15 | { 16 | "action": "aws:configureDocker", 17 | "name": "ConfigureDocker", 18 | "inputs": { 19 | "action": "{{ action }}" 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureS3BucketLogging: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Enables Logging on S3 Bucket", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "BucketName": { 7 | "type": "String", 8 | "description": "(Required) The name of the S3 Bucket whose logging will be configured." 9 | }, 10 | "GrantedPermission": { 11 | "type": "String", 12 | "description": "(Required) Logging permissions assigned to the Grantee for the bucket.", 13 | "allowedValues": [ 14 | "FULL_CONTROL", 15 | "READ", 16 | "WRITE" 17 | ] 18 | }, 19 | "GranteeType": { 20 | "type": "String", 21 | "description": "(Required) Type of grantee", 22 | "allowedValues": [ 23 | "CanonicalUser", 24 | "AmazonCustomerByEmail", 25 | "Group" 26 | ] 27 | }, 28 | "TargetBucket": { 29 | "type": "String", 30 | "description": "(Required) Specifies the bucket where you want Amazon S3 to store server access logs. You can have your logs delivered to any bucket that you own. You can also configure multiple buckets to deliver their logs to the same target bucket. In this case you should choose a different TargetPrefix for each source bucket so that the delivered log files can be distinguished by key." 31 | }, 32 | "GranteeEmailAddress": { 33 | "type": "String", 34 | "description": "(Optional) Email address of the grantee.", 35 | "default": "" 36 | }, 37 | "GranteeId": { 38 | "type": "String", 39 | "description": "(Optional) The canonical user ID of the grantee.", 40 | "default": "" 41 | }, 42 | "GranteeUri": { 43 | "type": "String", 44 | "description": "(Optional) URI of the grantee group.", 45 | "default": "" 46 | }, 47 | "TargetPrefix": { 48 | "type": "String", 49 | "description": "(Optional) Specifies a prefix for the keys under which the log files will be stored.", 50 | "default": "/" 51 | }, 52 | "AutomationAssumeRole": { 53 | "type": "String", 54 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 55 | "default": "" 56 | } 57 | }, 58 | "mainSteps": [ 59 | { 60 | "name": "PutBucketLoggingByUri", 61 | "isCritical": false, 62 | "action": "aws:executeAwsApi", 63 | "onFailure": "step:PutBucketLoggingById", 64 | "nextStep": "End", 65 | "inputs": { 66 | "Service": "s3", 67 | "Api": "PutBucketLogging", 68 | "Bucket": "{{BucketName}}", 69 | "BucketLoggingStatus": { 70 | "LoggingEnabled": { 71 | "TargetBucket": "{{TargetBucket}}", 72 | "TargetPrefix": "{{TargetPrefix}}", 73 | "TargetGrants": [ 74 | { 75 | "Grantee": { 76 | "Type": "{{GranteeType}}", 77 | "URI": "{{GranteeUri}}" 78 | }, 79 | "Permission": "{{GrantedPermission}}" 80 | } 81 | ] 82 | } 83 | } 84 | } 85 | }, 86 | { 87 | "name": "PutBucketLoggingById", 88 | "isCritical": false, 89 | "action": "aws:executeAwsApi", 90 | "onFailure": "step:PutBucketLoggingByEmailAddress", 91 | "nextStep": "End", 92 | "inputs": { 93 | "Service": "s3", 94 | "Api": "PutBucketLogging", 95 | "Bucket": "{{BucketName}}", 96 | "BucketLoggingStatus": { 97 | "LoggingEnabled": { 98 | "TargetBucket": "{{TargetBucket}}", 99 | "TargetPrefix": "{{TargetPrefix}}", 100 | "TargetGrants": [ 101 | { 102 | "Grantee": { 103 | "Type": "{{GranteeType}}", 104 | "ID": "{{GranteeId}}" 105 | }, 106 | "Permission": "{{GrantedPermission}}" 107 | } 108 | ] 109 | } 110 | } 111 | } 112 | }, 113 | { 114 | "name": "PutBucketLoggingByEmailAddress", 115 | "isCritical": true, 116 | "onFailure": "Abort", 117 | "action": "aws:executeAwsApi", 118 | "nextStep": "End", 119 | "inputs": { 120 | "Service": "s3", 121 | "Api": "PutBucketLogging", 122 | "Bucket": "{{BucketName}}", 123 | "BucketLoggingStatus": { 124 | "LoggingEnabled": { 125 | "TargetBucket": "{{TargetBucket}}", 126 | "TargetPrefix": "{{TargetPrefix}}", 127 | "TargetGrants": [ 128 | { 129 | "Grantee": { 130 | "Type": "{{GranteeType}}", 131 | "EmailAddress": "{{GranteeEmailAddress}}" 132 | }, 133 | "Permission": "{{GrantedPermission}}" 134 | } 135 | ] 136 | } 137 | } 138 | } 139 | }, 140 | { 141 | "name": "End", 142 | "action": "aws:sleep", 143 | "inputs": { 144 | "Duration": "PT1S" 145 | }, 146 | "isEnd": true 147 | } 148 | ] 149 | } 150 | -------------------------------------------------------------------------------- /documents/AWS-ConfigureS3BucketVersioning: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Configures the S3 Bucket's versioning", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "BucketName": { 7 | "type": "String", 8 | "description": "(Required) The name of the S3 Bucket whose encryption configuration will be managed." 9 | }, 10 | "VersioningState": { 11 | "type": "String", 12 | "description": "(Optional) Applied to the VersioningConfiguration.Status. When set to 'Enabled', this process enables versioning for the objects in the bucket, all objects added to the bucket receive a unique version ID. When set to 'Suspended', this process dsables versioning for the objects in the bucket, all objects added to the bucket receive the version ID null.\n", 13 | "default": "Enabled", 14 | "allowedValues": [ 15 | "Enabled", 16 | "Suspended" 17 | ] 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": "ConfigureVersioning", 28 | "action": "aws:executeAwsApi", 29 | "maxAttempts": 1, 30 | "inputs": { 31 | "Service": "s3", 32 | "Api": "PutBucketVersioning", 33 | "Bucket": "{{BucketName}}", 34 | "VersioningConfiguration": { 35 | "MFADelete": "Disabled", 36 | "Status": "{{VersioningState}}" 37 | } 38 | }, 39 | "isEnd": true 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /documents/AWS-CopySnapshot: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{ AutomationAssumeRole }}", 4 | "description": "Copy Snapshot", 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 region where the source snapshot currently exists." 13 | }, 14 | "Description": { 15 | "default": "", 16 | "type": "String", 17 | "description": "(Optional) A description for the EBS snapshot." 18 | }, 19 | "LambdaAssumeRole": { 20 | "default": "", 21 | "type": "String", 22 | "description": "(Optional) The ARN of the role assumed by lambda" 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 | "outputs": [ 31 | "copySnapshot.Payload" 32 | ], 33 | "mainSteps": [ 34 | { 35 | "action": "aws:createStack", 36 | "inputs": { 37 | "StackName": "CopySnapshotStack{{automation:EXECUTION_ID}}", 38 | "Parameters": [ 39 | { 40 | "ParameterValue": "{{LambdaAssumeRole}}", 41 | "ParameterKey": "LambdaRoleArn" 42 | }, 43 | { 44 | "ParameterValue": "CopySnapshotLambda-{{automation:EXECUTION_ID}}", 45 | "ParameterKey": "LambdaName" 46 | } 47 | ], 48 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'Assume role used by the lambda function.\n If not specified this template will create a temporarily role to be used by\n the lambda created in this template.\n\n ', Type: String}\nResources:\n CopySnapshotLambda:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\n\\n\\ndef handler(event,\\\n \\ context):\\n\\tec2_client = boto3.client(\\\"ec2\\\")\\n\\n\\tsnapshot_id = event[\\\"\\\n SnapshotId\\\"]\\n\\tsource_region = event[\\\"SourceRegion\\\"]\\n\\tdescription\\\n \\ = event[\\\"Description\\\"]\\n\\tresponse = ec2_client.copy_snapshot(\\n\\t\\t\\\n Description=description,\\n\\t\\tSourceRegion=source_region,\\n\\t\\tSourceSnapshotId=snapshot_id\\n\\\n \\t)\\n\\n\\treturn {\\n\\t\\t\\\"SnapshotId\\\": response[\\\"SnapshotId\\\"]\\n\\t}\\n\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['ec2:CopySnapshot']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: CopySnapshotLambdaPolicy\n Type: AWS::IAM::Role\n", 49 | "Capabilities": [ 50 | "CAPABILITY_IAM" 51 | ] 52 | }, 53 | "name": "createDocumentStack" 54 | }, 55 | { 56 | "action": "aws:invokeLambdaFunction", 57 | "inputs": { 58 | "FunctionName": "CopySnapshotLambda-{{automation:EXECUTION_ID}}", 59 | "Payload": "{\"SnapshotId\": \"{{SnapshotId}}\", \"SourceRegion\": \"{{SourceRegion}}\", \"Description\": \"{{Description}}\"}" 60 | }, 61 | "name": "copySnapshot" 62 | }, 63 | { 64 | "action": "aws:deleteStack", 65 | "inputs": { 66 | "StackName": "CopySnapshotStack{{automation:EXECUTION_ID}}" 67 | }, 68 | "name": "deleteCloudFormationTemplate" 69 | } 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /documents/AWS-CreateDynamoDbBackup: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Create DynamoDB table backup", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "TableName": { 7 | "type": "String", 8 | "description": "(Required) Name of the DynamoDB Table." 9 | }, 10 | "BackupName": { 11 | "type": "String", 12 | "description": "(Required) Name of the backup to create." 13 | }, 14 | "LambdaAssumeRole": { 15 | "type": "String", 16 | "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.", 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": "CreateDynamoDbBackupLambdaStack{{automation:EXECUTION_ID}}", 34 | "Parameters": [ 35 | { 36 | "ParameterKey": "LambdaRoleArn", 37 | "ParameterValue": "{{LambdaAssumeRole}}" 38 | }, 39 | { 40 | "ParameterKey": "CreateBackupLambdaName", 41 | "ParameterValue": "CreateDynamoDBBackup-{{automation:EXECUTION_ID}}" 42 | }, 43 | { 44 | "ParameterKey": "VerifySnapshotLambdaName", 45 | "ParameterValue": "VerifyDynamoDBBackup-{{automation:EXECUTION_ID}}" 46 | }, 47 | { 48 | "ParameterKey": "TableName", 49 | "ParameterValue": "{{TableName}}" 50 | } 51 | ], 52 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nParameters:\n CreateBackupLambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\n TableName: {Description: 'The name of the DynamoDB Table\n\n ', Type: String}\n VerifySnapshotLambdaName: {Description: 'The lambda function name\n\n ', Type: String}\nResources:\n CreateDynamoDbBackup:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\nfrom datetime import\\\n \\ datetime\\n\\nVAL_TABLE_NAME = \\\"TableName\\\"\\nVAL_DATE = \\\"Date\\\"\\nVAL_DATETIME\\\n \\ = \\\"Datetime\\\"\\nVAL_TIME = \\\"Time\\\"\\nVAL_EXECUTION_ID = \\\"ExecutionId\\\"\\\n \\n\\nVAL_STR = \\\"{{{}}}\\\"\\n\\n\\ndef placeholder_data(ctx, tag_vars):\\n\\tdef\\\n \\ clean(s):\\n\\t\\treturn s.replace(\\\":\\\", \\\"\\\").replace(\\\"T\\\", \\\"\\\").replace(\\\"\\\n -\\\", \\\"\\\")\\n\\n\\tdt = datetime.now().replace(microsecond=0)\\n\\tdata = {\\n\\\n \\t\\tVAL_DATETIME: clean(dt.isoformat()),\\n\\t\\tVAL_DATE: clean(dt.date().isoformat()),\\n\\\n \\t\\tVAL_TIME: clean(dt.time().isoformat()),\\n\\t\\tVAL_EXECUTION_ID: \\\"-\\\"\\\n .join(ctx.function_name.split(\\\"-\\\")[-5:]) if ctx is not None else \\\"\\\"\\n\\\n \\t}\\n\\n\\tif tag_vars is not None:\\n\\t\\tfor t in tag_vars:\\n\\t\\t\\tdata[t]\\\n \\ = tag_vars[t]\\n\\treturn data\\n\\n\\ndef template_string(s, context, s_vars=None):\\n\\\n \\tif s == \\\"\\\":\\n\\t\\treturn \\\"\\\"\\n\\n\\tplaceholders = placeholder_data(ctx=context,\\\n \\ tag_vars=s_vars)\\n\\tfor p in placeholders:\\n\\t\\ts = s.replace(VAL_STR.format(p),\\\n \\ str(placeholders[p]))\\n\\treturn s\\n\\n\\ndef handler(event, context):\\n\\t\\\n client = boto3.client(\\\"dynamodb\\\")\\n\\n\\ttable_name = event[\\\"TableName\\\"\\\n ].strip()\\n\\tbackup_name = template_string(event[\\\"BackupName\\\"].strip(),\\\n \\ context, {VAL_TABLE_NAME: table_name})\\n\\n\\tresp = client.create_backup(TableName=table_name,\\\n \\ BackupName=backup_name)\\n\\n\\treturn resp[\\\"BackupDetails\\\"][\\\"BackupArn\\\"\\\n ]\\n\\n\\n\"}\n FunctionName: {Ref: CreateBackupLambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n - Action: ['dynamodb:DescribeBackup']\n Effect: Allow\n Resource: '*'\n - Action: ['dynamodb:CreateBackup']\n Effect: Allow\n Resource:\n Fn::Join:\n - ''\n - - Fn::Join:\n - ':'\n - - arn:aws:dynamodb\n - {Ref: 'AWS::Region'}\n - {Ref: 'AWS::AccountId'}\n - table/\n - {Ref: TableName}\n Version: '2012-10-17'\n PolicyName: CreateDynamoDbBackupLambdaPolicy\n Type: AWS::IAM::Role\n VerifyDynamoDbBackup:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\nimport time\\n\\ndb_client\\\n \\ = boto3.client('dynamodb')\\n\\n\\ndef handler(event, context):\\n\\tbackup_arn\\\n \\ = event[\\\"BackupArn\\\"]\\n\\n\\twhile True:\\n\\t\\ttry:\\n\\t\\t\\tstatus = db_client.describe_backup(BackupArn=backup_arn)[\\\"\\\n BackupDescription\\\"][\\\"BackupDetails\\\"][\\\"BackupStatus\\\"]\\n\\t\\t\\tif status\\\n \\ == \\\"AVAILABLE\\\":\\n\\t\\t\\t\\treturn\\n\\n\\t\\t\\ttime.sleep(10)\\n\\n\\t\\texcept\\\n \\ Exception as e:\\n\\t\\t\\tprint(e)\\n\\t\\t\\ttime.sleep(10)\\n\\t\\t\\tpass\\n\"}\n FunctionName: {Ref: VerifySnapshotLambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 300\n Type: AWS::Lambda::Function\n" 53 | } 54 | }, 55 | { 56 | "name": "createDynamoDbBackup", 57 | "action": "aws:invokeLambdaFunction", 58 | "inputs": { 59 | "FunctionName": "CreateDynamoDBBackup-{{automation:EXECUTION_ID}}", 60 | "Payload": "{\"TableName\": \"{{TableName}}\", \"BackupName\": \"{{BackupName}}\"}" 61 | } 62 | }, 63 | { 64 | "name": "verifyBackup", 65 | "action": "aws:invokeLambdaFunction", 66 | "maxAttempts": 10, 67 | "inputs": { 68 | "FunctionName": "VerifyDynamoDBBackup-{{automation:EXECUTION_ID}}", 69 | "Payload": "{\"BackupArn\": \"{{createDynamoDbBackup.Payload}}\"}" 70 | } 71 | }, 72 | { 73 | "name": "deleteCloudFormationTemplate", 74 | "action": "aws:deleteStack", 75 | "inputs": { 76 | "StackName": "CreateDynamoDbBackupLambdaStack{{automation:EXECUTION_ID}}" 77 | } 78 | } 79 | ], 80 | "outputs": [ 81 | "createDynamoDbBackup.Payload" 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /documents/AWS-CreateImage: -------------------------------------------------------------------------------- 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 | "NoReboot": { 11 | "type": "Boolean", 12 | "description": "(Optional) Do not reboot the instance before creating the image.", 13 | "default": false 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": "createImage", 24 | "action": "aws:createImage", 25 | "onFailure": "Abort", 26 | "inputs": { 27 | "InstanceId": "{{ InstanceId }}", 28 | "ImageName": "{{ InstanceId }}_{{automation:EXECUTION_ID}}", 29 | "NoReboot": "{{ NoReboot }}" 30 | } 31 | } 32 | ], 33 | "outputs": [ 34 | "createImage.ImageId" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /documents/AWS-CreateJiraIssue: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Creates a Jira issue.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "JiraUsername": { 7 | "type": "String", 8 | "description": "(Required) The name of the user the issue will be created with." 9 | }, 10 | "SSMParameterName": { 11 | "type": "String", 12 | "description": "(Required) The name of an encrypted SSM Parameter containing the API key or password for the Jira user." 13 | }, 14 | "JiraURL": { 15 | "type": "String", 16 | "description": "(Required) The url of the Jira instance." 17 | }, 18 | "ProjectKey": { 19 | "type": "String", 20 | "description": "(Required) The key of the project the issue should be created in." 21 | }, 22 | "IssueSummary": { 23 | "type": "String", 24 | "description": "(Required) A brief summary of the issue." 25 | }, 26 | "IssueDescription": { 27 | "type": "String", 28 | "description": "(Required) A detailed description of the issue." 29 | }, 30 | "IssueTypeName": { 31 | "type": "String", 32 | "description": "(Required) The name of the type of issue you want to create (ex. Task, Sub-task, Bug, etc)." 33 | }, 34 | "PriorityName": { 35 | "type": "String", 36 | "description": "(Optional) The name of the priority of the issue.", 37 | "default": "" 38 | }, 39 | "AssigneeName": { 40 | "type": "String", 41 | "description": "(Optional) The username of the person the issue should be assigned to.", 42 | "default": "" 43 | }, 44 | "DueDate": { 45 | "type": "String", 46 | "description": "(Optional) The due date for the issue in yyyy-mm-dd format.", 47 | "default": "" 48 | }, 49 | "LambdaAssumeRole": { 50 | "type": "String", 51 | "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.", 52 | "default": "" 53 | }, 54 | "AutomationAssumeRole": { 55 | "type": "String", 56 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 57 | "default": "" 58 | } 59 | }, 60 | "mainSteps": [ 61 | { 62 | "name": "createDocumentStack", 63 | "action": "aws:createStack", 64 | "inputs": { 65 | "Capabilities": [ 66 | "CAPABILITY_IAM" 67 | ], 68 | "StackName": "CreateJiraIssueLambdaStack{{automation:EXECUTION_ID}}", 69 | "Parameters": [ 70 | { 71 | "ParameterKey": "LambdaRoleArn", 72 | "ParameterValue": "{{LambdaAssumeRole}}" 73 | }, 74 | { 75 | "ParameterKey": "LambdaName", 76 | "ParameterValue": "CreateJiraIssueLambda-{{automation:EXECUTION_ID}}" 77 | }, 78 | { 79 | "ParameterKey": "SSMParameterName", 80 | "ParameterValue": "{{SSMParameterName}}" 81 | } 82 | ], 83 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\n SSMParameterName: {Description: 'The name of the SSM Parameter with the Jira password/token\n\n ', Type: String}\nResources:\n CreateJiraIssue:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\nimport json\\nfrom\\\n \\ botocore.vendored import requests\\n\\ndef add_priority(issue, priority):\\n\\\n \\tfields = issue[\\\"fields\\\"]\\n\\tfields[\\\"priority\\\"] = {\\\"name\\\": priority}\\n\\\n \\ndef add_assignee(issue, assignee):\\n\\tfields = issue[\\\"fields\\\"]\\n\\tfields[\\\"\\\n assignee\\\"] = {\\\"name\\\": assignee}\\n\\ndef add_due_date(issue, due_date):\\n\\\n \\tfields = issue[\\\"fields\\\"]\\n\\tfields[\\\"duedate\\\"] = due_date\\n\\ndef handler(event,\\\n \\ context):\\n\\n\\tclient = boto3.client(\\\"ssm\\\")\\n\\n\\tssm_parameter_name\\\n \\ = event[\\\"SSMParameterName\\\"].strip()\\n\\n\\tsecret = client.get_parameter(Name=ssm_parameter_name,\\\n \\ WithDecryption=True)['Parameter']['Value']\\n\\n\\tusername = event[\\\"JiraUsername\\\"\\\n ].strip()\\n\\turl = event[\\\"JiraURL\\\"].strip()\\n\\n\\tissue = {\\n\\t\\t\\\"fields\\\"\\\n : {\\n\\t\\t\\t\\\"summary\\\": event[\\\"IssueSummary\\\"].strip(),\\n\\t\\t\\t\\\"project\\\"\\\n : {\\n\\t\\t\\t\\t\\\"key\\\": event[\\\"ProjectKey\\\"].strip()\\n\\t\\t\\t},\\n\\t\\t\\t\\\"\\\n description\\\": event[\\\"IssueDescription\\\"].strip(),\\n\\t\\t\\t\\\"issuetype\\\"\\\n : {\\n\\t\\t\\t\\t\\\"name\\\": event[\\\"IssueTypeName\\\"].strip()\\n\\t\\t\\t}\\n\\t\\t}\\n\\\n \\t}\\n\\n\\tpriority = event[\\\"PriorityName\\\"].strip()\\n\\tif priority:\\n\\t\\t\\\n add_priority(issue, priority)\\n\\n\\tassignee = event[\\\"AssigneeName\\\"].strip()\\n\\\n \\tif assignee:\\n\\t\\tadd_assignee(issue, assignee)\\n\\n\\tdue_date = event[\\\"\\\n DueDate\\\"].strip()\\n\\tif due_date:\\n\\t\\tadd_due_date(issue, due_date)\\n\\n\\\n \\tdata = json.dumps(issue)\\n\\n\\theaders = {'Content-Type':'application/json'}\\n\\\n \\n\\tresponse = requests.post('{0}/rest/api/2/issue/'.format(url),\\n\\t\\t\\t\\\n \\t\\t\\t\\t headers=headers,\\n\\t\\t\\t\\t\\t\\t\\t data=data,\\n\\t\\t\\t\\t\\t\\t\\t auth=(username,\\\n \\ secret))\\n\\n\\tif not response.ok:\\n\\t\\traise Exception(\\\"Received error\\\n \\ with status code \\\" + str(response.status_code) + \\\" from Jira\\\")\\n\\t\\\n else:\\n\\t\\tissue_key = (response.json()[\\\"key\\\"])\\n\\t\\treturn {\\\"IssueKey\\\"\\\n : issue_key}\\n\\n\\n\\n\\n\\n\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 300\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n - Action: ['ssm:GetParameter']\n Effect: Allow\n Resource:\n Fn::Join:\n - ''\n - - Fn::Join:\n - ':'\n - - arn\n - {Ref: 'AWS::Partition'}\n - ssm\n - {Ref: 'AWS::Region'}\n - {Ref: 'AWS::AccountId'}\n - parameter/\n - {Ref: SSMParameterName}\n Version: '2012-10-17'\n PolicyName: CreateJiraIssueLambdaPolicy\n Type: AWS::IAM::Role\n" 84 | } 85 | }, 86 | { 87 | "name": "createJiraIssue", 88 | "action": "aws:invokeLambdaFunction", 89 | "inputs": { 90 | "FunctionName": "CreateJiraIssueLambda-{{automation:EXECUTION_ID}}", 91 | "Payload": "{\"JiraUsername\": \"{{JiraUsername}}\", \"SSMParameterName\": \"{{SSMParameterName}}\", \"JiraURL\": \"{{JiraURL}}\", \"ProjectKey\": \"{{ProjectKey}}\", \"IssueSummary\": \"{{IssueSummary}}\", \"IssueDescription\": \"{{IssueDescription}}\", \"IssueTypeName\": \"{{IssueTypeName}}\", \"PriorityName\": \"{{PriorityName}}\", \"AssigneeName\": \"{{AssigneeName}}\", \"DueDate\": \"{{DueDate}}\"}" 92 | } 93 | }, 94 | { 95 | "name": "deleteCloudFormationTemplate", 96 | "action": "aws:deleteStack", 97 | "inputs": { 98 | "StackName": "CreateJiraIssueLambdaStack{{automation:EXECUTION_ID}}" 99 | } 100 | } 101 | ], 102 | "outputs": [ 103 | "createJiraIssue.Payload" 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /documents/AWS-CreateSnapshot: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "Create EBS volume snapshot", 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 | "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": "createSnapshot", 24 | "action": "aws:executeAwsApi", 25 | "inputs": { 26 | "Service": "ec2", 27 | "Api": "CreateSnapshot", 28 | "VolumeId": "{{ VolumeId }}", 29 | "Description": "{{ Description }}" 30 | }, 31 | "outputs": [ 32 | { 33 | "Name": "Payload", 34 | "Selector": "SnapshotId", 35 | "Type": "String" 36 | } 37 | ] 38 | }, 39 | { 40 | "name": "verifySnapshot", 41 | "action": "aws:waitForAwsResourceProperty", 42 | "timeoutSeconds": 600, 43 | "inputs": { 44 | "Service": "ec2", 45 | "Api": "DescribeSnapshots", 46 | "SnapshotIds": [ 47 | "{{createSnapshot.Payload}}" 48 | ], 49 | "PropertySelector": "Snapshots[0].State", 50 | "DesiredValues": [ 51 | "completed" 52 | ] 53 | } 54 | } 55 | ], 56 | "outputs": [ 57 | "createSnapshot.Payload" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /documents/AWS-DeleteCloudFormationStack: -------------------------------------------------------------------------------- 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/AWS-DeleteCloudFormationStackWithApproval: -------------------------------------------------------------------------------- 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/AWS-DeleteDynamoDbBackup: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete DynamoDB table backup", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "BackupArn": { 7 | "type": "String", 8 | "description": "(Required) ARN of the DynamoDB table backup to delete." 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": "DeleteDynamoDbBackup", 19 | "action": "aws:executeAwsApi", 20 | "inputs": { 21 | "Service": "dynamodb", 22 | "Api": "DeleteBackup", 23 | "BackupArn": "{{BackupArn}}" 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /documents/AWS-DeleteDynamoDbTableBackups: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Deletes DynamoDB table backups based on retention days 'OR' count.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "TableName": { 7 | "type": "String", 8 | "description": "(Required) Name of the DynamoDB Table." 9 | }, 10 | "RetentionCount": { 11 | "type": "String", 12 | "description": "(Optional) The number of backups to retain for the table. If more than the specified number of backup exist, the oldest backups beyond that number are deleted. Either RetentionCount or RetentionDays can be used, not both.", 13 | "default": "10" 14 | }, 15 | "RetentionDays": { 16 | "type": "String", 17 | "description": "(Optional) The number of days to retain backups for the table. Backups older than the specified number of days are deleted. Either RetentionCount or RetentionDays can be used, not both.", 18 | "default": "" 19 | }, 20 | "LambdaAssumeRole": { 21 | "type": "String", 22 | "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.", 23 | "default": "" 24 | }, 25 | "AutomationAssumeRole": { 26 | "type": "String", 27 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", 28 | "default": "" 29 | } 30 | }, 31 | "mainSteps": [ 32 | { 33 | "name": "createDocumentStack", 34 | "action": "aws:createStack", 35 | "inputs": { 36 | "Capabilities": [ 37 | "CAPABILITY_IAM" 38 | ], 39 | "StackName": "DeleteDynamoDbTableBackupsLambaStack{{automation:EXECUTION_ID}}", 40 | "Parameters": [ 41 | { 42 | "ParameterKey": "LambdaRoleArn", 43 | "ParameterValue": "{{LambdaAssumeRole}}" 44 | }, 45 | { 46 | "ParameterKey": "LambdaName", 47 | "ParameterValue": "DeleteTableBackupsLambda-{{automation:EXECUTION_ID}}" 48 | }, 49 | { 50 | "ParameterKey": "TableName", 51 | "ParameterValue": "{{TableName}}" 52 | } 53 | ], 54 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\n TableName: {Description: 'The name of the DynamoDB Table for which backups are deleted\n\n ', Type: String}\nResources:\n DeleteDynamoDbTableBackups:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\nimport boto3\\nfrom datetime import\\\n \\ datetime, timedelta, tzinfo\\n\\nZERO = timedelta(0)\\n\\n\\nclass UTC(tzinfo):\\n\\\n \\n\\tdef utcoffset(self, dt):\\n\\t\\treturn ZERO\\n\\n\\tdef tzname(self, dt):\\n\\\n \\t\\treturn \\\"UTC\\\"\\n\\n\\tdef dst(self, dt):\\n\\t\\treturn ZERO\\n\\ndef handler(event,\\\n \\ context):\\n\\n\\tdef get_table_backups(client, tablename):\\n\\n\\t\\targs =\\\n \\ {\\n\\t\\t\\t\\\"TableName\\\" : tablename\\n\\t\\t}\\n\\n\\t\\twhile True:\\n\\t\\t\\tresp\\\n \\ = client.list_backups(**args)\\n\\t\\t\\tfor backup in resp.get(\\\"BackupSummaries\\\"\\\n , []):\\n\\t\\t\\t\\tyield backup\\n\\t\\t\\tif \\\"LastEvaluatedBackupArn\\\" in resp:\\n\\\n \\t\\t\\t\\targs[\\\"ExclusiveStartBackupArn\\\"] = resp[\\\"LastEvaluatedBackupArn\\\"\\\n ]\\n\\t\\t\\telse:\\n\\t\\t\\t\\tbreak\\n\\n\\tclient = boto3.client(\\\"dynamodb\\\")\\n\\\n \\n\\ttable_name = event[\\\"TableName\\\"].strip()\\n\\ttry:\\n\\t\\tretention_count\\\n \\ = int(event.get(\\\"RetentionCount\\\", \\\"0\\\").strip('\\\"').strip())\\n\\texcept:\\n\\\n \\t\\tretention_count = 0\\n\\n\\ttry:\\n\\t\\tretention_days = int(event.get(\\\"\\\n RetentionDays\\\", \\\"0\\\").strip('\\\"').strip())\\n\\texcept:\\n\\t\\tretention_days\\\n \\ = 0\\n\\n\\tif (retention_count == 0) and (retention_days == 0):\\n\\t\\traise\\\n \\ ValueError(\\\"RetentionCount or RetentionDays parameter must be specified\\\"\\\n )\\n\\n\\tif (retention_count > 0) and (retention_days > 0):\\n\\t\\traise ValueError(\\\"\\\n Only one of RetentionCount or RetentionDays parameters can be specified\\\"\\\n )\\n\\n\\tbackups = sorted(get_table_backups(client, table_name), key=lambda\\\n \\ b: b[\\\"BackupCreationDateTime\\\"], reverse=True)\\n\\n\\tdeleting = []\\n\\n\\\n \\tdelete_before = datetime.utcnow().replace(tzinfo=UTC()) - timedelta(days=int(retention_days))\\n\\\n \\n\\tif retention_days > 0:\\n\\t\\ti = 0\\n\\t\\twhile i < len(backups):\\n\\t\\t\\\n \\tif backups[i][\\\"BackupCreationDateTime\\\"] < delete_before:\\n\\t\\t\\t\\tdeleting.append(backups.pop(i)[\\\"\\\n BackupArn\\\"])\\n\\t\\t\\telse:\\n\\t\\t\\t\\ti += 1\\n\\n\\tif retention_count > 0:\\n\\\n \\t\\tif retention_count > 0:\\n\\t\\t\\tdeleting += [b[\\\"BackupArn\\\"] for b in\\\n \\ backups[retention_count:]]\\n\\n\\tfor backup_arn in deleting:\\n\\t\\tclient.delete_backup(BackupArn=backup_arn)\\n\\\n \\n\\treturn {\\n\\t\\t\\\"DeletedBackupsArns\\\": deleting\\n\\t}\\n\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n - Action: ['dynamodb:ListBackups']\n Effect: Allow\n Resource: '*'\n - Action: ['dynamodb:DeleteBackup']\n Effect: Allow\n Resource:\n Fn::Join:\n - ''\n - - Fn::Join:\n - ':'\n - - arn:aws:dynamodb\n - {Ref: 'AWS::Region'}\n - {Ref: 'AWS::AccountId'}\n - table/\n - {Ref: TableName}\n - /backup/*\n Version: '2012-10-17'\n PolicyName: DeleteDynamoDbTableBackupsLambdaPolicy\n Type: AWS::IAM::Role\n" 55 | } 56 | }, 57 | { 58 | "name": "deleteDynamoDbTableBackups", 59 | "action": "aws:invokeLambdaFunction", 60 | "inputs": { 61 | "FunctionName": "DeleteTableBackupsLambda-{{automation:EXECUTION_ID}}", 62 | "Payload": "{\"TableName\": \"{{TableName}}\", \"RetentionCount\": \"{{RetentionCount}}\", \"RetentionDays\": \"{{RetentionDays}}\"}" 63 | } 64 | }, 65 | { 66 | "name": "deleteCloudFormationTemplate", 67 | "action": "aws:deleteStack", 68 | "inputs": { 69 | "StackName": "DeleteDynamoDbTableBackupsLambaStack{{automation:EXECUTION_ID}}" 70 | } 71 | } 72 | ], 73 | "outputs": [ 74 | "deleteDynamoDbTableBackups.Payload" 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /documents/AWS-DeleteEbsVolumeSnapshots: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Delete EBS Volume snapshots", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "VolumeId": { 7 | "type": "String", 8 | "description": "(Required) The volume identifier to delete snapshots for." 9 | }, 10 | "RetentionCount": { 11 | "type": "String", 12 | "description": "(Optional) Number of snapshots to keep for the volume. Either RetentionCount or RetentionDays should be mentioned, not both.", 13 | "default": "10" 14 | }, 15 | "RetentionDays": { 16 | "type": "String", 17 | "description": "(Optional) Number of days to keep snapshots for the volume. Either RetentionCount or RetentionDays should be mentioned, not both", 18 | "default": "" 19 | }, 20 | "LambdaAssumeRole": { 21 | "type": "String", 22 | "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.", 23 | "default": "" 24 | }, 25 | "AutomationAssumeRole": { 26 | "type": "String", 27 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 28 | "default": "" 29 | } 30 | }, 31 | "mainSteps": [ 32 | { 33 | "name": "createDocumentStack", 34 | "action": "aws:createStack", 35 | "inputs": { 36 | "Capabilities": [ 37 | "CAPABILITY_IAM" 38 | ], 39 | "StackName": "deleteVolumeSnapshotsLambdaStack{{automation:EXECUTION_ID}}", 40 | "Parameters": [ 41 | { 42 | "ParameterKey": "LambdaRoleArn", 43 | "ParameterValue": "{{LambdaAssumeRole}}" 44 | }, 45 | { 46 | "ParameterKey": "LambdaName", 47 | "ParameterValue": "DeleteVolumeSnapshotsLambda-{{automation:EXECUTION_ID}}" 48 | } 49 | ], 50 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\nResources:\n DeleteSnapshotsLambda:\n Properties:\n Code: {ZipFile: \"#\\n# Copyright 2018 Amazon.com, Inc. or its affiliates. All\\\n \\ Rights Reserved.\\n#\\n# Permission is hereby granted, free of charge, to\\\n \\ any person obtaining a copy of this\\n# software and associated documentation\\\n \\ files (the \\\"Software\\\"), to deal in the Software\\n# without restriction,\\\n \\ including without limitation the rights to use, copy, modify,\\n# merge,\\\n \\ publish, distribute, sublicense, and/or sell copies of the Software, and\\\n \\ to\\n# permit persons to whom the Software is furnished to do so.\\n#\\n\\\n # THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\n \\ OR IMPLIED,\\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\\n \\ FITNESS FOR A\\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\\\n \\ THE AUTHORS OR COPYRIGHT\\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\\\n \\ OTHER LIABILITY, WHETHER IN AN ACTION\\n# OF CONTRACT, TORT OR OTHERWISE,\\\n \\ ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n# SOFTWARE OR THE USE\\\n \\ OR OTHER DEALINGS IN THE SOFTWARE.\\n#\\n\\nimport boto3\\nimport time\\nfrom\\\n \\ datetime import datetime, timedelta, tzinfo\\n\\nZERO = timedelta(0)\\n\\n\\\n \\nclass UTC(tzinfo):\\n\\n\\tdef utcoffset(self, dt):\\n\\t\\treturn ZERO\\n\\n\\t\\\n def tzname(self, dt):\\n\\t\\treturn \\\"UTC\\\"\\n\\n\\tdef dst(self, dt):\\n\\t\\t\\\n return ZERO\\n\\n\\ndef get_volume_snapshots(client, volume_id):\\n\\targs =\\\n \\ {\\n\\t\\t\\\"Filters\\\": [\\n\\t\\t\\t{\\n\\t\\t\\t\\t\\\"Name\\\": \\\"volume-id\\\",\\n\\t\\t\\\n \\t\\t\\\"Values\\\": [volume_id]},\\n\\t\\t\\t{\\n\\t\\t\\t\\t\\\"Name\\\": \\\"status\\\",\\n\\t\\\n \\t\\t\\t\\\"Values\\\": [\\\"completed\\\"]\\n\\t\\t\\t}\\n\\t\\t],\\n\\t\\t\\\"OwnerIds\\\": [\\\"\\\n self\\\"]\\n\\n\\t}\\n\\tsnapshots = []\\n\\twhile True:\\n\\t\\tresp = client.describe_snapshots(**args)\\n\\\n \\t\\tsnapshots += resp.get(\\\"Snapshots\\\", [])\\n\\t\\tif \\\"NextToken\\\" in resp:\\n\\\n \\t\\t\\targs[\\\"NextToken\\\"] = resp[\\\"NextToken\\\"]\\n\\t\\telse:\\n\\t\\t\\tbreak\\n\\\n \\n\\treturn snapshots\\n\\n\\ndef delete_snapshot(client, snapshot_id):\\n\\t\\\n wait_period = 5\\n\\tretries = 5\\n\\twhile True:\\n\\t\\ttry:\\n\\t\\t\\tclient.delete_snapshot(SnapshotId=snapshot_id)\\n\\\n \\t\\t\\treturn True\\n\\t\\texcept Exception as ex:\\n\\t\\t\\t# As the list of snapshot\\\n \\ is eventually consistent old snapshots might appear in listed snapshots\\n\\\n \\t\\t\\tif getattr(ex, \\\"response\\\", {}).get(\\\"Error\\\", {}).get(\\\"Code\\\",\\\n \\ \\\"\\\") == \\\"'InvalidSnapshot.NotFound\\\":\\n\\t\\t\\t\\treturn False\\n\\t\\t\\t\\\n # Throttling might occur when deleting snapshots too fast\\n\\t\\t\\tif \\\"throttling\\\"\\\n \\ in ex.message.lower():\\n\\t\\t\\t\\tretries -= 1\\n\\t\\t\\t\\tif retries == 0:\\n\\\n \\t\\t\\t\\t\\traise ex\\n\\t\\t\\t\\ttime.sleep(wait_period)\\n\\t\\t\\t\\twait_period\\\n \\ = min(wait_period + 10 , 30)\\n\\t\\t\\t\\tcontinue\\n\\t\\t\\traise ex\\n\\n\\ndef\\\n \\ handler(event, context):\\n\\tclient = boto3.client(\\\"ec2\\\")\\n\\n\\tsnapshot_id\\\n \\ = event[\\\"VolumeId\\\"].strip()\\n\\ttry:\\n\\t\\tretention_count = int(event.get(\\\"\\\n RetentionCount\\\", \\\"0\\\").strip('\\\"').strip())\\n\\texcept:\\n\\t\\tretention_count\\\n \\ = 0\\n\\n\\ttry:\\n\\t\\tretention_days = int(event.get(\\\"RetentionDays\\\", \\\"\\\n 0\\\").strip('\\\"').strip())\\n\\texcept:\\n\\t\\tretention_days = 0\\n\\n\\tif (retention_count\\\n \\ == 0) and (retention_days == 0):\\n\\t\\traise ValueError(\\\"RetentionCount\\\n \\ or RetentionDays parameter must be specified\\\")\\n\\n\\tif (retention_count\\\n \\ > 0) and (retention_days > 0):\\n\\t\\traise ValueError(\\\"Only one of RetentionCount\\\n \\ or RetentionDays parameters can be specified\\\")\\n\\n\\tsnapshots_for_volume\\\n \\ = sorted(get_volume_snapshots(client, snapshot_id), key=lambda s: s[\\\"\\\n StartTime\\\"], reverse=True)\\n\\n\\tsnapshots_to_delete = []\\n\\n\\tif retention_days\\\n \\ > 0:\\n\\t\\tdelete_before = datetime.utcnow().replace(tzinfo=UTC()) - timedelta(days=int(retention_days))\\n\\\n \\t\\ti = 0\\n\\t\\twhile i < len(snapshots_for_volume):\\n\\t\\t\\tif snapshots_for_volume[i][\\\"\\\n StartTime\\\"] < delete_before:\\n\\t\\t\\t\\tsnapshots_to_delete.append(snapshots_for_volume.pop(i)[\\\"\\\n SnapshotId\\\"])\\n\\t\\t\\telse:\\n\\t\\t\\t\\ti += 1\\n\\n\\telif retention_count >\\\n \\ 0:\\n\\t\\tsnapshots_to_delete = [b[\\\"SnapshotId\\\"] for b in snapshots_for_volume[retention_count:]]\\n\\\n \\n\\tsnapshots_deleted = []\\n\\tfor snapshot_id in snapshots_to_delete:\\n\\t\\\n \\tif delete_snapshot(client, snapshot_id):\\n\\t\\t\\tsnapshots_deleted.append(snapshot_id)\\n\\\n \\n\\treturn {\\n\\t\\t\\\"DeletedSnapshots\\\": snapshots_deleted\\n\\t}\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['ec2:DescribeSnapshots', 'ec2:DeleteSnapshot']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: DeleteVolumeSnapshotsLambdaPolicy\n Type: AWS::IAM::Role\n" 51 | } 52 | }, 53 | { 54 | "name": "deleteVolumeSnapshots", 55 | "action": "aws:invokeLambdaFunction", 56 | "inputs": { 57 | "FunctionName": "DeleteVolumeSnapshotsLambda-{{automation:EXECUTION_ID}}", 58 | "Payload": "{\"VolumeId\": \"{{VolumeId}}\", \"RetentionCount\": \"{{RetentionCount}}\", \"RetentionDays\": \"{{RetentionDays}}\"}" 59 | } 60 | }, 61 | { 62 | "name": "deleteCloudFormationTemplate", 63 | "action": "aws:deleteStack", 64 | "inputs": { 65 | "StackName": "deleteVolumeSnapshotsLambdaStack{{automation:EXECUTION_ID}}" 66 | } 67 | } 68 | ], 69 | "outputs": [ 70 | "deleteVolumeSnapshots.Payload" 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /documents/AWS-DeleteImage: -------------------------------------------------------------------------------- 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 | "onFailure": "Abort", 21 | "inputs": { 22 | "ImageId": "{{ ImageId }}" 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /documents/AWS-DeleteSnapshot: -------------------------------------------------------------------------------- 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 | "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": "DeleteSnapshot", 19 | "action": "aws:executeAwsApi", 20 | "inputs": { 21 | "Service": "ec2", 22 | "Api": "DeleteSnapshot", 23 | "SnapshotId": "{{SnapshotId}}" 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /documents/AWS-DetachEBSVolume: -------------------------------------------------------------------------------- 1 | { 2 | "assumeRole": "{{ AutomationAssumeRole }}", 3 | "description": "Detach EBS Volume", 4 | "parameters": { 5 | "VolumeId": { 6 | "type": "String", 7 | "description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" 8 | }, 9 | "LambdaAssumeRole": { 10 | "default": "", 11 | "type": "String", 12 | "description": "(Optional) The ARN of the role assumed by lambda" 13 | }, 14 | "AutomationAssumeRole": { 15 | "default": "", 16 | "type": "String", 17 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. " 18 | } 19 | }, 20 | "outputs": [ 21 | "detachVolume.LogResult" 22 | ], 23 | "schemaVersion": "0.3", 24 | "mainSteps": [ 25 | { 26 | "action": "aws:createStack", 27 | "inputs": { 28 | "StackName": "DetachEBSVolumeStack{{automation:EXECUTION_ID}}", 29 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nConditions:\n LambdaAssumeRoleNotSpecified:\n Fn::Or:\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - ''\n - Fn::Equals:\n - {Ref: LambdaRoleArn}\n - undefined\nDescription: Automation Stack for Detach EBS Volumes\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\nResources:\n DetachVolumeLambda:\n Properties:\n Code: {ZipFile: \"import boto3\\nimport time\\nimport logging\\n\\nlogger = logging.getLogger()\\n\\\n logger.setLevel(logging.INFO)\\n\\n\\ndef handler(event, context):\\n\\tec2 =\\\n \\ boto3.resource('ec2')\\n\\n\\tvolume_id = event[\\\"VolumeId\\\"]\\n\\tvolume =\\\n \\ ec2.Volume(volume_id)\\n\\tvolume.detach_from_instance()\\n\\n\\tretry_count\\\n \\ = 0\\n\\tattachment_state = 'detaching'\\n\\n\\twhile retry_count < 35:\\n\\n\\\n \\t\\tretry_count += 1\\n\\t\\tvolume.reload()\\n\\n\\t\\tif len(volume.attachments)\\\n \\ == 0:\\n\\t\\t\\tattachment_state = 'detached'\\n\\t\\t\\tbreak\\n\\t\\tattachment_state\\\n \\ = volume.attachments[0]['State']\\n\\t\\tif attachment_state == 'detached'\\\n \\ or attachment_state == 'busy':\\n\\t\\t\\tbreak\\n\\n\\t\\ttime.sleep(1)\\n\\t\\t\\\n logger.info(\\\"Current Attachment State:\\\" + attachment_state + \\\", tries:\\\"\\\n \\ + str(retry_count))\\n\\n\\tlogger.info(\\\"Last Attachment State:\\\" + attachment_state\\\n \\ + \\\", tries:\\\" + str(retry_count))\\n\\n\\tif attachment_state == 'busy':\\n\\\n \\t\\tlogger.warn('Volume still mounted. Will detach once volume is unmounted\\\n \\ from instance.')\\n\\t\\traise Exception('Volume still mounted. Will detach\\\n \\ once volume is unmounted from instance.')\\n\\n\\tif attachment_state !=\\\n \\ 'detached':\\n\\t\\traise Exception('Failed to detach volume. Current state\\\n \\ is:' + attachment_state)\\n\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role:\n Fn::If:\n - LambdaAssumeRoleNotSpecified\n - Fn::GetAtt: [LambdaRole, Arn]\n - {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n LambdaRole:\n Condition: LambdaAssumeRoleNotSpecified\n Properties:\n AssumeRolePolicyDocument:\n Statement:\n - Action: ['sts:AssumeRole']\n Effect: Allow\n Principal:\n Service: [lambda.amazonaws.com]\n Version: '2012-10-17'\n Path: /\n Policies:\n - PolicyDocument:\n Statement:\n Action: ['ec2:DescribeVolumes', 'ec2:DetachVolume']\n Effect: Allow\n Resource: '*'\n Version: '2012-10-17'\n PolicyName: DetachVolumeLambdaPolicy\n Type: AWS::IAM::Role\n", 30 | "Parameters": [ 31 | { 32 | "ParameterValue": "{{LambdaAssumeRole}}", 33 | "ParameterKey": "LambdaRoleArn" 34 | }, 35 | { 36 | "ParameterValue": "DetachVolumeLambda-{{automation:EXECUTION_ID}}", 37 | "ParameterKey": "LambdaName" 38 | } 39 | ], 40 | "Capabilities": [ 41 | "CAPABILITY_IAM" 42 | ] 43 | }, 44 | "name": "createDocumentStack" 45 | }, 46 | { 47 | "action": "aws:invokeLambdaFunction", 48 | "inputs": { 49 | "LogType": "Tail", 50 | "FunctionName": "DetachVolumeLambda-{{automation:EXECUTION_ID}}", 51 | "Payload": "{\"VolumeId\": \"{{VolumeId}}\"}" 52 | }, 53 | "name": "detachVolume" 54 | }, 55 | { 56 | "action": "aws:deleteStack", 57 | "inputs": { 58 | "StackName": "DetachEBSVolumeStack{{automation:EXECUTION_ID}}" 59 | }, 60 | "name": "deleteCloudFormationTemplate" 61 | } 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /documents/AWS-DisablePublicAccessForSecurityGroup: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Disable SSH and RDP ports opened to IP address specified, or to all addresses if no address is specified.", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "GroupId": { 7 | "type": "String", 8 | "description": "(Required) Security Group ID", 9 | "allowedPattern": "^([s][g]\\-)([0-9a-f]){1,}$" 10 | }, 11 | "IpAddressToBlock": { 12 | "type": "String", 13 | "description": "(Optional) Additional Ipv4 or Ipv6 address to block access from (ex:1.2.3.4/32)", 14 | "allowedPattern": "(^$)|^((25[0-5]|(2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|(^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?))|(^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}))\\/(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)$", 15 | "default": "" 16 | }, 17 | "AutomationAssumeRole": { 18 | "type": "String", 19 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 20 | "default": "" 21 | } 22 | }, 23 | "mainSteps": [ 24 | { 25 | "name": "CustomIpCheck", 26 | "action": "aws:branch", 27 | "inputs": { 28 | "Choices": [ 29 | { 30 | "NextStep": "DisableFromCustomIpV6", 31 | "And": [ 32 | { 33 | "Not": { 34 | "Variable": "{{IpAddressToBlock}}", 35 | "StringEquals": "" 36 | } 37 | }, 38 | { 39 | "Variable": "{{ IpAddressToBlock }}", 40 | "Contains": ":" 41 | } 42 | ] 43 | }, 44 | { 45 | "NextStep": "DisableFromCustomIpV4", 46 | "And": [ 47 | { 48 | "Not": { 49 | "Variable": "{{IpAddressToBlock}}", 50 | "StringEquals": "" 51 | } 52 | }, 53 | { 54 | "Not": { 55 | "Variable": "{{ IpAddressToBlock }}", 56 | "Contains": ":" 57 | } 58 | } 59 | ] 60 | } 61 | ], 62 | "Default": "DisableFromAllIp" 63 | } 64 | }, 65 | { 66 | "name": "DisableFromAllIp", 67 | "action": "aws:executeAwsApi", 68 | "inputs": { 69 | "Service": "ec2", 70 | "Api": "RevokeSecurityGroupIngress", 71 | "GroupId": "{{GroupId}}", 72 | "IpPermissions": [ 73 | { 74 | "IpProtocol": "tcp", 75 | "FromPort": 22, 76 | "ToPort": 22, 77 | "IpRanges": [ 78 | { 79 | "CidrIp": "0.0.0.0/0" 80 | } 81 | ] 82 | }, 83 | { 84 | "IpProtocol": "tcp", 85 | "FromPort": 22, 86 | "ToPort": 22, 87 | "Ipv6Ranges": [ 88 | { 89 | "CidrIpv6": "::/0" 90 | } 91 | ] 92 | }, 93 | { 94 | "IpProtocol": "tcp", 95 | "FromPort": 3389, 96 | "ToPort": 3389, 97 | "IpRanges": [ 98 | { 99 | "CidrIp": "0.0.0.0/0" 100 | } 101 | ] 102 | }, 103 | { 104 | "IpProtocol": "tcp", 105 | "FromPort": 3389, 106 | "ToPort": 3389, 107 | "Ipv6Ranges": [ 108 | { 109 | "CidrIpv6": "::/0" 110 | } 111 | ] 112 | } 113 | ] 114 | }, 115 | "isEnd": true 116 | }, 117 | { 118 | "name": "DisableFromCustomIpV4", 119 | "action": "aws:executeAwsApi", 120 | "inputs": { 121 | "Service": "ec2", 122 | "Api": "RevokeSecurityGroupIngress", 123 | "GroupId": "{{GroupId}}", 124 | "IpPermissions": [ 125 | { 126 | "IpProtocol": "tcp", 127 | "FromPort": 22, 128 | "ToPort": 22, 129 | "IpRanges": [ 130 | { 131 | "CidrIp": "{{ IpAddressToBlock }}" 132 | } 133 | ] 134 | }, 135 | { 136 | "IpProtocol": "tcp", 137 | "FromPort": 3389, 138 | "ToPort": 3389, 139 | "IpRanges": [ 140 | { 141 | "CidrIp": "{{ IpAddressToBlock }}" 142 | } 143 | ] 144 | } 145 | ] 146 | }, 147 | "isEnd": true 148 | }, 149 | { 150 | "name": "DisableFromCustomIpV6", 151 | "action": "aws:executeAwsApi", 152 | "inputs": { 153 | "Service": "ec2", 154 | "Api": "RevokeSecurityGroupIngress", 155 | "GroupId": "{{GroupId}}", 156 | "IpPermissions": [ 157 | { 158 | "IpProtocol": "tcp", 159 | "FromPort": 22, 160 | "ToPort": 22, 161 | "Ipv6Ranges": [ 162 | { 163 | "CidrIpv6": "{{ IpAddressToBlock }}" 164 | } 165 | ] 166 | }, 167 | { 168 | "IpProtocol": "tcp", 169 | "FromPort": 3389, 170 | "ToPort": 3389, 171 | "Ipv6Ranges": [ 172 | { 173 | "CidrIpv6": "{{ IpAddressToBlock }}" 174 | } 175 | ] 176 | } 177 | ] 178 | }, 179 | "isEnd": true 180 | } 181 | ] 182 | } 183 | -------------------------------------------------------------------------------- /documents/AWS-DisableS3BucketPublicReadWrite: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Disable S3-Bucket's public WriteRead access via private ACL", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "S3BucketName": { 7 | "type": "String", 8 | "description": "(Required) S3 Bucket subject to access restriction" 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": "DisableS3BucketPublicReadWrite", 19 | "action": "aws:executeAwsApi", 20 | "inputs": { 21 | "Service": "s3", 22 | "Api": "PutBucketAcl", 23 | "Bucket": "{{S3BucketName}}", 24 | "ACL": "private" 25 | }, 26 | "isEnd": true 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /documents/AWS-EnableCloudTrail: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Enable CloudTrail", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "TrailName": { 7 | "type": "String", 8 | "description": "(Required) The name of the new trail." 9 | }, 10 | "S3BucketName": { 11 | "type": "String", 12 | "description": "(Required) Name of the Amazon S3 bucket designated for publishing log files." 13 | }, 14 | "AutomationAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 17 | "default": "" 18 | } 19 | }, 20 | "mainSteps": [ 21 | { 22 | "name": "EnableCloudTrail", 23 | "action": "aws:executeAwsApi", 24 | "inputs": { 25 | "Service": "cloudtrail", 26 | "Api": "CreateTrail", 27 | "Name": "{{TrailName}}", 28 | "S3BucketName": "{{S3BucketName}}" 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /documents/AWS-EnableS3BucketEncryption: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Enables Encryption on S3 Bucket", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "BucketName": { 7 | "type": "String", 8 | "description": "(Required) The name of the S3 Bucket whose content will be encrypted." 9 | }, 10 | "SSEAlgorithm": { 11 | "type": "String", 12 | "description": "(Optional) Server-side encryption algorithm to use for the default encryption.", 13 | "default": "AES256" 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": "PutBucketEncryption", 24 | "action": "aws:executeAwsApi", 25 | "inputs": { 26 | "Service": "s3", 27 | "Api": "PutBucketEncryption", 28 | "Bucket": "{{BucketName}}", 29 | "ServerSideEncryptionConfiguration": { 30 | "Rules": [ 31 | { 32 | "ApplyServerSideEncryptionByDefault": { 33 | "SSEAlgorithm": "{{SSEAlgorithm}}" 34 | } 35 | } 36 | ] 37 | } 38 | }, 39 | "isEnd": true 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /documents/AWS-GatherSoftwareInventory: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Software Inventory Policy Document.", 4 | "parameters": { 5 | "applications": { 6 | "type": "String", 7 | "default": "Enabled", 8 | "description": "(Optional) Collect data for installed applications.", 9 | "allowedValues": [ 10 | "Enabled", 11 | "Disabled" 12 | ] 13 | }, 14 | "awsComponents": { 15 | "type": "String", 16 | "default": "Enabled", 17 | "description": "(Optional) Collect data for AWS Components like amazon-ssm-agent.", 18 | "allowedValues": [ 19 | "Enabled", 20 | "Disabled" 21 | ] 22 | }, 23 | "files": { 24 | "type": "String", 25 | "default": "", 26 | "description": "

(Optional, requires SSMAgent version 2.2.64.0 and above)

Linux example:
[{\"Path\":\"/usr/bin\", \"Pattern\":[\"aws*\", \"*ssm*\"],\"Recursive\":false},{\"Path\":\"/var/log\", \"Pattern\":[\"amazon*.*\"], \"Recursive\":true, \"DirScanLimit\":1000}]

Windows example:
[{\"Path\":\"%PROGRAMFILES%\", \"Pattern\":[\"*.exe\"],\"Recursive\":true}]

Learn More: http://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-about.html#sysman-inventory-file-and-registry

", 27 | "displayType": "textarea" 28 | }, 29 | "networkConfig": { 30 | "type": "String", 31 | "default": "Enabled", 32 | "description": "(Optional) Collect data for Network configurations.", 33 | "allowedValues": [ 34 | "Enabled", 35 | "Disabled" 36 | ] 37 | }, 38 | "windowsUpdates": { 39 | "type": "String", 40 | "default": "Enabled", 41 | "description": "(Optional, Windows OS only) Collect data for all Windows Updates.", 42 | "allowedValues": [ 43 | "Enabled", 44 | "Disabled" 45 | ] 46 | }, 47 | "instanceDetailedInformation": { 48 | "type": "String", 49 | "default": "Enabled", 50 | "description": "(Optional) Collect additional information about the instance, including the CPU model, speed, and the number of cores, to name a few.", 51 | "allowedValues": [ 52 | "Enabled", 53 | "Disabled" 54 | ] 55 | }, 56 | "services": { 57 | "type": "String", 58 | "default": "Enabled", 59 | "description": "(Optional, Windows OS only, requires SSMAgent version 2.2.64.0 and above) Collect data for service configurations.", 60 | "allowedValues": [ 61 | "Enabled", 62 | "Disabled" 63 | ] 64 | }, 65 | "windowsRegistry": { 66 | "type": "String", 67 | "default": "", 68 | "description": "

(Optional, Windows OS only, requires SSMAgent version 2.2.64.0 and above)

Example:
[{\"Path\":\"HKEY_CURRENT_CONFIG\\System\",\"Recursive\":true},{\"Path\":\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Amazon\\MachineImage\", \"ValueNames\":[\"AMIName\"]}]

Learn More: http://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-about.html#sysman-inventory-file-and-registry

", 69 | "displayType": "textarea" 70 | }, 71 | "windowsRoles": { 72 | "type": "String", 73 | "default": "Enabled", 74 | "description": "(Optional, Windows OS only, requires SSMAgent version 2.2.64.0 and above) Collect data for Microsoft Windows role configurations.", 75 | "allowedValues": [ 76 | "Enabled", 77 | "Disabled" 78 | ] 79 | }, 80 | "customInventory": { 81 | "type": "String", 82 | "default": "Enabled", 83 | "description": "(Optional) Collect data for custom inventory.", 84 | "allowedValues": [ 85 | "Enabled", 86 | "Disabled" 87 | ] 88 | }, 89 | "billingInfo": { 90 | "type": "String", 91 | "default": "Enabled", 92 | "description": "(Optional) Collect billing info for license included applications.", 93 | "allowedValues": [ 94 | "Enabled", 95 | "Disabled" 96 | ] 97 | } 98 | }, 99 | "mainSteps": [ 100 | { 101 | "action": "aws:softwareInventory", 102 | "name": "collectSoftwareInventoryItems", 103 | "inputs": { 104 | "applications": "{{ applications }}", 105 | "awsComponents": "{{ awsComponents }}", 106 | "networkConfig": "{{ networkConfig }}", 107 | "files": "{{ files }}", 108 | "services": "{{ services }}", 109 | "windowsRoles": "{{ windowsRoles }}", 110 | "windowsRegistry": "{{ windowsRegistry}}", 111 | "windowsUpdates": "{{ windowsUpdates }}", 112 | "instanceDetailedInformation": "{{ instanceDetailedInformation }}", 113 | "billingInfo": "{{ billingInfo }}", 114 | "customInventory": "{{ customInventory }}" 115 | } 116 | } 117 | ] 118 | } 119 | -------------------------------------------------------------------------------- /documents/AWS-InstallApplication: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Install, repair, or uninstall an application using an .msi file.", 4 | "parameters": { 5 | "action": { 6 | "type": "String", 7 | "default": "Install", 8 | "description": "(Optional) The type of action to perform. Valid values: Install | Repair | Uninstall", 9 | "allowedValues": [ 10 | "Install", 11 | "Repair", 12 | "Uninstall" 13 | ] 14 | }, 15 | "parameters": { 16 | "type": "String", 17 | "default": "", 18 | "description": "(Optional) The parameters for the installer." 19 | }, 20 | "source": { 21 | "type": "String", 22 | "description": "(Required) The URL or local path on the instance to the application .msi file." 23 | }, 24 | "sourceHash": { 25 | "type": "String", 26 | "default": "", 27 | "description": "(Optional) The SHA256 hash of the .msi file." 28 | } 29 | }, 30 | "runtimeConfig": { 31 | "aws:applications": { 32 | "properties": [ 33 | { 34 | "id": "0.aws:applications", 35 | "action": "{{ action }}", 36 | "parameters": "{{ parameters }}", 37 | "source": "{{ source }}", 38 | "sourceHash": "{{ sourceHash }}" 39 | } 40 | ] 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /documents/AWS-InstallPowerShellModule: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Deploy and install PowerShell modules.", 4 | "parameters": { 5 | "workingDirectory": { 6 | "type": "String", 7 | "default": "", 8 | "description": "(Optional) The path to the working directory on your instance.", 9 | "maxChars": 4096 10 | }, 11 | "source": { 12 | "type": "String", 13 | "description": "(Optional) The URL or local path on the instance to the application .zip file." 14 | }, 15 | "sourceHash": { 16 | "type": "String", 17 | "default": "", 18 | "description": "(Optional) The SHA256 hash of the zip file." 19 | }, 20 | "commands": { 21 | "type": "StringList", 22 | "default": [], 23 | "description": "(Optional) Specify PowerShell commands to run on your instance.", 24 | "displayType": "textarea" 25 | }, 26 | "executionTimeout": { 27 | "type": "String", 28 | "default": "3600", 29 | "description": "(Optional) The time in seconds for a command to be completed before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).", 30 | "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)" 31 | } 32 | }, 33 | "runtimeConfig": { 34 | "aws:psModule": { 35 | "properties": [ 36 | { 37 | "id": "0.aws:psModule", 38 | "runCommand": "{{ commands }}", 39 | "source": "{{ source }}", 40 | "sourceHash": "{{ sourceHash }}", 41 | "workingDirectory": "{{ workingDirectory }}", 42 | "timeoutSeconds": "{{ executionTimeout }}" 43 | } 44 | ] 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /documents/AWS-JoinDirectoryServiceDomain: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Join your instances to an AWS Directory Service domain.", 4 | "parameters": { 5 | "directoryId": { 6 | "type": "String", 7 | "description": "(Required) The ID of the AWS Directory Service directory." 8 | }, 9 | "directoryName": { 10 | "type": "String", 11 | "description": "(Required) The name of the directory; for example, test.example.com" 12 | }, 13 | "directoryOU": { 14 | "type": "String", 15 | "default": "", 16 | "description": "(Optional) The Organizational Unit (OU) and Directory Components (DC) for the directory; for example, OU=test,DC=example,DC=com" 17 | }, 18 | "dnsIpAddresses": { 19 | "type": "StringList", 20 | "default": [], 21 | "description": "(Optional) The IP addresses of the DNS servers in the directory. Required when DHCP is not configured. Learn more at http://docs.aws.amazon.com/directoryservice/latest/simple-ad/join_get_dns_addresses.html", 22 | "allowedPattern": "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 23 | } 24 | }, 25 | "runtimeConfig": { 26 | "aws:domainJoin": { 27 | "properties": { 28 | "directoryId": "{{ directoryId }}", 29 | "directoryName": "{{ directoryName }}", 30 | "directoryOU": "{{ directoryOU }}", 31 | "dnsIpAddresses": "{{ dnsIpAddresses }}" 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /documents/AWS-PasswordReset: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.0", 3 | "description": "Document to reset a user's password on an instance", 4 | "sessionType": "InteractiveCommands", 5 | "parameters": { 6 | "username": { 7 | "type": "String", 8 | "description": "The username for which the password needs to be reset on an instance", 9 | "allowedPattern": "^[a-zA-Z0-9\\_.@-]*$", 10 | "minChars": 1, 11 | "maxChars": 256 12 | } 13 | }, 14 | "properties": { 15 | "windows": { 16 | "commands": "net user {{username}} *", 17 | "runAsElevated": true 18 | }, 19 | "linux": { 20 | "commands": "passwd {{username}}", 21 | "runAsElevated": true 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /documents/AWS-PatchAsgInstance: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Systems Manager Automation - Patch instances in an Auto Scaling Group", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) ID of the Instance to patch. Only specify when not running from Maintenance Windows." 9 | }, 10 | "WaitForReboot": { 11 | "type": "String", 12 | "description": "(Optional) How long Automation should sleep for, to allow a patched instance to reboot", 13 | "default": "PT5M" 14 | }, 15 | "WaitForInstance": { 16 | "type": "String", 17 | "description": "(Optional) How long Automation should sleep for, to allow the instance come back into service", 18 | "default": "PT2M" 19 | }, 20 | "LambdaRoleArn": { 21 | "default": "", 22 | "type": "String", 23 | "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." 24 | }, 25 | "AutomationAssumeRole": { 26 | "type": "String", 27 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 28 | "default": "" 29 | } 30 | }, 31 | "mainSteps": [ 32 | { 33 | "name": "createPatchGroupTags", 34 | "action": "aws:createTags", 35 | "maxAttempts": 1, 36 | "onFailure": "Continue", 37 | "inputs": { 38 | "ResourceType": "EC2", 39 | "ResourceIds": [ 40 | "{{InstanceId}}" 41 | ], 42 | "Tags": [ 43 | { 44 | "Key": "AutoPatchInstanceInASG", 45 | "Value": "InProgress" 46 | } 47 | ] 48 | } 49 | }, 50 | { 51 | "name": "EnterStandby", 52 | "action": "aws:executeAutomation", 53 | "maxAttempts": 1, 54 | "timeoutSeconds": 300, 55 | "onFailure": "Abort", 56 | "inputs": { 57 | "DocumentName": "AWS-ASGEnterStandby", 58 | "RuntimeParameters": { 59 | "InstanceId": [ 60 | "{{InstanceId}}" 61 | ], 62 | "LambdaRoleArn": [ 63 | "{{LambdaRoleArn}}" 64 | ], 65 | "AutomationAssumeRole": [ 66 | "{{AutomationAssumeRole}}" 67 | ] 68 | } 69 | } 70 | }, 71 | { 72 | "name": "installMissingOSUpdates", 73 | "action": "aws:runCommand", 74 | "maxAttempts": 1, 75 | "onFailure": "Continue", 76 | "inputs": { 77 | "DocumentName": "AWS-RunPatchBaseline", 78 | "InstanceIds": [ 79 | "{{InstanceId}}" 80 | ], 81 | "Parameters": { 82 | "Operation": "Install" 83 | } 84 | } 85 | }, 86 | { 87 | "name": "SleepToCompleteInstall", 88 | "action": "aws:sleep", 89 | "inputs": { 90 | "Duration": "{{WaitForReboot}}" 91 | } 92 | }, 93 | { 94 | "name": "ExitStandby", 95 | "action": "aws:executeAutomation", 96 | "maxAttempts": 1, 97 | "timeoutSeconds": 300, 98 | "onFailure": "Abort", 99 | "inputs": { 100 | "DocumentName": "AWS-ASGExitStandby", 101 | "RuntimeParameters": { 102 | "InstanceId": [ 103 | "{{InstanceId}}" 104 | ], 105 | "LambdaRoleArn": [ 106 | "{{LambdaRoleArn}}" 107 | ], 108 | "AutomationAssumeRole": [ 109 | "{{AutomationAssumeRole}}" 110 | ] 111 | } 112 | } 113 | }, 114 | { 115 | "name": "CompletePatchGroupTags", 116 | "action": "aws:createTags", 117 | "maxAttempts": 1, 118 | "onFailure": "Continue", 119 | "inputs": { 120 | "ResourceType": "EC2", 121 | "ResourceIds": [ 122 | "{{InstanceId}}" 123 | ], 124 | "Tags": [ 125 | { 126 | "Key": "AutoPatchInstanceInASG", 127 | "Value": "Completed" 128 | } 129 | ] 130 | } 131 | }, 132 | { 133 | "name": "SleepBeforeNextInstance", 134 | "action": "aws:sleep", 135 | "inputs": { 136 | "Duration": "{{WaitForInstance}}" 137 | } 138 | } 139 | ] 140 | } 141 | -------------------------------------------------------------------------------- /documents/AWS-PublishSNSNotification: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Publish SNS Notification", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "TopicArn": { 7 | "type": "String", 8 | "description": "(Required) The ARN of the SNS topic to publish the notification to." 9 | }, 10 | "Message": { 11 | "type": "String", 12 | "description": "(Required) The message to include in the SNS notification." 13 | }, 14 | "AutomationAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 17 | "default": "" 18 | } 19 | }, 20 | "mainSteps": [ 21 | { 22 | "name": "PublishSNSNotification", 23 | "action": "aws:executeAwsApi", 24 | "inputs": { 25 | "Service": "sns", 26 | "Api": "Publish", 27 | "TopicArn": "{{TopicArn}}", 28 | "Message": "{{Message}}" 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /documents/AWS-RebootRdsInstance: -------------------------------------------------------------------------------- 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 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "AssertNotRebooting", 19 | "action": "aws:assertAwsResourceProperty", 20 | "isCritical": false, 21 | "onFailure": "step:RebootInstance", 22 | "nextStep": "WaitForAvailableState", 23 | "inputs": { 24 | "Service": "rds", 25 | "Api": "DescribeDBInstances", 26 | "DBInstanceIdentifier": "{{InstanceId}}", 27 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 28 | "DesiredValues": [ 29 | "rebooting" 30 | ] 31 | } 32 | }, 33 | { 34 | "name": "RebootInstance", 35 | "action": "aws:executeAwsApi", 36 | "inputs": { 37 | "Service": "rds", 38 | "Api": "RebootDBInstance", 39 | "DBInstanceIdentifier": "{{InstanceId}}" 40 | } 41 | }, 42 | { 43 | "name": "WaitForAvailableState", 44 | "action": "aws:waitForAwsResourceProperty", 45 | "maxAttempts": 10, 46 | "timeoutSeconds": 600, 47 | "onFailure": "Abort", 48 | "inputs": { 49 | "Service": "rds", 50 | "Api": "DescribeDBInstances", 51 | "DBInstanceIdentifier": "{{InstanceId}}", 52 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 53 | "DesiredValues": [ 54 | "available" 55 | ] 56 | }, 57 | "isEnd": true 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /documents/AWS-RefreshAssociation: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Refresh (force apply) the association on demand. This action will change the system state based on what is defined in the selected association or all associations bound to the targets.", 4 | "parameters": { 5 | "associationIds": { 6 | "type": "StringList", 7 | "description": "(Optional) List of association ids. If empty, all associations bound to the specified target are applied.", 8 | "displayType": "textarea", 9 | "default": [] 10 | } 11 | }, 12 | "mainSteps": [ 13 | { 14 | "action": "aws:refreshAssociation", 15 | "name": "refreshAssociation", 16 | "inputs": { 17 | "associationIds": "{{ associationIds }}" 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /documents/AWS-ReleaseElasticIP: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Release ElasticIP", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "AllocationId": { 7 | "type": "String", 8 | "description": "(Required) The Allocation ID of the Elastic IP address." 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": "ReleaseElasticIp", 19 | "action": "aws:executeAwsApi", 20 | "inputs": { 21 | "Service": "ec2", 22 | "Api": "ReleaseAddress", 23 | "AllocationId": "{{AllocationId}}" 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /documents/AWS-ResizeInstance: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Resize an EC2 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 desired instance type" 13 | }, 14 | "AutomationAssumeRole": { 15 | "type": "String", 16 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.", 17 | "default": "" 18 | } 19 | }, 20 | "mainSteps": [ 21 | { 22 | "name": "assertInstanceType", 23 | "action": "aws:assertAwsResourceProperty", 24 | "inputs": { 25 | "Service": "EC2", 26 | "Api": "DescribeInstances", 27 | "InstanceIds": [ 28 | "{{InstanceId}}" 29 | ], 30 | "PropertySelector": "$.Reservations[0].Instances[0].InstanceType", 31 | "DesiredValues": [ 32 | "{{InstanceType}}" 33 | ] 34 | }, 35 | "onFailure": "step:stopInstance", 36 | "isCritical": false, 37 | "isEnd": true 38 | }, 39 | { 40 | "name": "stopInstance", 41 | "action": "aws:changeInstanceState", 42 | "inputs": { 43 | "InstanceIds": [ 44 | "{{InstanceId}}" 45 | ], 46 | "DesiredState": "stopped" 47 | } 48 | }, 49 | { 50 | "name": "resizeInstance", 51 | "action": "aws:executeAwsApi", 52 | "inputs": { 53 | "Service": "EC2", 54 | "Api": "ModifyInstanceAttribute", 55 | "InstanceId": "{{InstanceId}}", 56 | "InstanceType": { 57 | "Value": "{{InstanceType}}" 58 | } 59 | } 60 | }, 61 | { 62 | "name": "wait", 63 | "action": "aws:sleep", 64 | "inputs": { 65 | "Duration": "PT5S" 66 | } 67 | }, 68 | { 69 | "name": "startInstance", 70 | "action": "aws:changeInstanceState", 71 | "inputs": { 72 | "InstanceIds": [ 73 | "{{InstanceId}}" 74 | ], 75 | "DesiredState": "running" 76 | } 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /documents/AWS-RestartEC2Instance: -------------------------------------------------------------------------------- 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/AWS-RestartEC2InstanceWithApproval: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Restart 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 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/AWS-RunAnsiblePlaybook: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Use this document to run Ansible playbooks on Amazon EC2 managed instances. Specify either YAML text or URL. If you specify both, the URL parameter will be used. Use the extravar parameter to send runtime variables to the Ansible execution. Use the check parameter to perform a dry run of the Ansible execution. The output of the dry run shows the changes that will be made when the playbook is executed.", 4 | "parameters": { 5 | "playbook": { 6 | "type": "String", 7 | "description": "(Optional) If you don't specify a URL, then you must specify playbook YAML in this field.", 8 | "default": "", 9 | "displayType": "textarea" 10 | }, 11 | "playbookurl": { 12 | "type": "String", 13 | "description": "(Optional) If you don't specify playbook YAML, then you must specify a URL where the playbook is stored. You can specify the URL in the following formats: http://example.com/playbook.yml or s3://examplebucket/plabook.url. For security reasons, you can't specify a URL with quotes.", 14 | "default": "", 15 | "allowedPattern": "^\\s*$|^(http|https|s3)://[^']*$" 16 | }, 17 | "extravars": { 18 | "type": "String", 19 | "description": "(Optional) Additional variables to pass to Ansible at runtime. Enter a space separated list of key/value pairs. For example: color=red flavor=lime", 20 | "default": "SSM=True", 21 | "displayType": "textarea", 22 | "allowedPattern": "^$|^\\w+\\=\\S+(\\s\\w+\\=\\S+)*$" 23 | }, 24 | "check": { 25 | "type": "String", 26 | "description": " (Optional) Use the check parameter to perform a dry run of the Ansible execution.", 27 | "allowedValues": [ 28 | "True", 29 | "False" 30 | ], 31 | "default": "False" 32 | } 33 | }, 34 | "mainSteps": [ 35 | { 36 | "action": "aws:runShellScript", 37 | "name": "runShellScript", 38 | "inputs": { 39 | "runCommand": [ 40 | "#!/bin/bash", 41 | "ansible --version", 42 | "if [ $? -ne 0 ]; then", 43 | " echo \"Ansible is not installed. Please install Ansible and rerun the command\" >&2", 44 | " exit 1", 45 | "fi", 46 | "execdir=$(dirname $0)", 47 | "cd $execdir", 48 | "if [ -z '{{playbook}}' ] ; then", 49 | " if [[ \"{{playbookurl}}\" == http* ]]; then", 50 | " wget '{{playbookurl}}' -O playbook.yml", 51 | " if [ $? -ne 0 ]; then", 52 | " echo \"There was a problem downloading the playbook. Make sure the URL is correct and that the playbook exists.\" >&2", 53 | " exit 1", 54 | " fi", 55 | " elif [[ \"{{playbookurl}}\" == s3* ]] ; then", 56 | " aws --version", 57 | " if [ $? -ne 0 ]; then", 58 | " echo \"The AWS CLI is not installed. The CLI is required to process Amazon S3 URLs. Install the AWS CLI and run the command again.\" >&2", 59 | " exit 1", 60 | " fi", 61 | " aws s3 cp '{{playbookurl}}' playbook.yml", 62 | " if [ $? -ne 0 ]; then", 63 | " echo \"Error while downloading the document from S3\" >&2", 64 | " exit 1", 65 | " fi", 66 | " else", 67 | " echo \"The playbook URL is not valid. Verify the URL and try again.\"", 68 | " fi", 69 | "else", 70 | " echo '{{playbook}}' > playbook.yml", 71 | "fi", 72 | "if [[ \"{{check}}\" == True ]] ; then", 73 | " ansible-playbook -i \"localhost,\" --check -c local -e \"{{extravars}}\" playbook.yml", 74 | "else", 75 | " ansible-playbook -i \"localhost,\" -c local -e \"{{extravars}}\" playbook.yml", 76 | "fi" 77 | ] 78 | } 79 | } 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /documents/AWS-RunDockerAction: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Run Docker actions on containers.", 4 | "parameters": { 5 | "action": { 6 | "type": "String", 7 | "description": "The type of action to perform.", 8 | "allowedValues": [ 9 | "Create", 10 | "Start", 11 | "Run", 12 | "Stop", 13 | "Rm", 14 | "Exec", 15 | "Inspect", 16 | "Logs", 17 | "Ps", 18 | "Stats", 19 | "Pull", 20 | "Images", 21 | "Rmi" 22 | ] 23 | }, 24 | "container": { 25 | "type": "String", 26 | "default": "", 27 | "description": "(Optional) The Docker container Id.", 28 | "allowedPattern": "^[a-zA-Z0-9_\\-\\/]*$", 29 | "maxChars": 128 30 | }, 31 | "image": { 32 | "type": "String", 33 | "default": "", 34 | "description": "(Optional) The Docker image name.", 35 | "allowedPattern": "^[a-zA-Z0-9_\\-\\/]*$", 36 | "maxChars": 128 37 | }, 38 | "cmd": { 39 | "type": "String", 40 | "default": "", 41 | "description": "(Optional) The container command.", 42 | "allowedPattern": "^[^;,&|]*$", 43 | "maxChars": 128 44 | }, 45 | "memory": { 46 | "type": "String", 47 | "default": "", 48 | "description": "(Optional) The container memory limit.", 49 | "allowedPattern": "^[0-9]*[bkmg]?$", 50 | "maxChars": 10 51 | }, 52 | "cpuShares": { 53 | "type": "String", 54 | "default": "", 55 | "description": "(Optional) The container CPU shares (relative weight).", 56 | "allowedPattern": "^/?[a-zA-Z0-9_-]*$", 57 | "maxChars": 10 58 | }, 59 | "volume": { 60 | "type": "StringList", 61 | "default": [], 62 | "description": "(Optional) The container volume mounts.", 63 | "displayType": "textarea", 64 | "allowedPattern": "^[\\w\\\\\\/_\\:\\-\\.\\\"\\(\\)\\^ ]*$", 65 | "maxChars": 128 66 | }, 67 | "env": { 68 | "type": "String", 69 | "default": "", 70 | "description": "(Optional) The container environment variables.", 71 | "allowedPattern": "^[^;,&|]*$", 72 | "maxChars": 256 73 | }, 74 | "user": { 75 | "type": "String", 76 | "default": "", 77 | "description": "(Optional) The container username.", 78 | "allowedPattern": "^[a-zA-Z0-9_-]*$", 79 | "maxChars": 128 80 | }, 81 | "publish": { 82 | "type": "String", 83 | "default": "", 84 | "description": "(Optional) The container published ports.", 85 | "allowedPattern": "^[0-9a-zA-Z:\\-\\/.]*$", 86 | "maxChars": 50 87 | } 88 | }, 89 | "mainSteps": [ 90 | { 91 | "action": "aws:runDockerAction", 92 | "name": "RunDockerAction", 93 | "inputs": { 94 | "action": "{{ action }}", 95 | "container": "{{ container }}", 96 | "image": "{{ image }}", 97 | "memory": "{{ memory }}", 98 | "cpuShares": "{{ cpuShares }}", 99 | "volume": "{{ volume }}", 100 | "cmd": "{{ cmd }}", 101 | "env": "{{ env }}", 102 | "user": "{{ user }}", 103 | "publish": "{{ publish }}" 104 | } 105 | } 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /documents/AWS-RunDocument: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Execute composite or nested Systems Manager documents (SSM documents) stored in a remote location. The following remote locations are currently supported: GitHub (public and private), Amazon S3 (S3), and Systems Manager documents. The following SSM document types are currently supported: JSON and YAML.", 4 | "parameters": { 5 | "sourceType": { 6 | "description": "(Required) Specify the source type.", 7 | "type": "String", 8 | "allowedValues": [ 9 | "GitHub", 10 | "S3", 11 | "SSMDocument" 12 | ] 13 | }, 14 | "sourceInfo": { 15 | "description": "(Required) Specify the information required to access the resource from the source. If source type is GitHub, then you can specify any of the following: 'owner', 'repository', 'path', 'getOptions', 'tokenInfo'. If source type is S3, then you can specify 'path'. If source type is SSM document, then you can specify 'name'.", 16 | "type": "StringMap", 17 | "displayType": "textarea", 18 | "default": {} 19 | }, 20 | "documentParameters": { 21 | "description": "(Optional) Parameters to be passed to the SSM document that will be executed.", 22 | "type": "StringMap", 23 | "displayType": "textarea", 24 | "default": {} 25 | } 26 | }, 27 | "mainSteps": [ 28 | { 29 | "action": "aws:downloadContent", 30 | "name": "downloadContent", 31 | "inputs": { 32 | "sourceType": "{{ sourceType }}", 33 | "sourceInfo": "{{ sourceInfo }}", 34 | "destinationPath": "ssmdocument" 35 | } 36 | }, 37 | { 38 | "action": "aws:runDocument", 39 | "name": "runDocument", 40 | "inputs": { 41 | "documentType": "LocalPath", 42 | "documentPath": "ssmdocument", 43 | "documentParameters": "{{ documentParameters }}" 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /documents/AWS-RunInspecChecks: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Run a single InSpec test or an InSpec profile on a group of managed instances.", 4 | "parameters": { 5 | "sourceType": { 6 | "description": "(Required) Specify the source type.", 7 | "type": "String", 8 | "allowedValues": [ 9 | "GitHub", 10 | "S3" 11 | ] 12 | }, 13 | "sourceInfo": { 14 | "description": "(Required) Specify the information required to access the resource from the source. If source type is GitHub, then you can specify any of the following: 'owner', 'repository', 'path', 'getOptions', 'tokenInfo'. If source type is S3, then you can specify 'path'. Example github parameters: {\"owner\":\"awslabs\",\"repository\":\"amazon-ssm\",\"path\":\"Compliance/InSpec/PortCheck\",\"getOptions\":\"branch:master\"}", 15 | "type": "StringMap", 16 | "displayType": "textarea", 17 | "default": {} 18 | } 19 | }, 20 | "mainSteps": [ 21 | { 22 | "action": "aws:downloadContent", 23 | "name": "downloadContent", 24 | "inputs": { 25 | "sourceType": "{{ sourceType }}", 26 | "sourceInfo": "{{ sourceInfo }}" 27 | } 28 | }, 29 | { 30 | "precondition": { 31 | "StringEquals": [ 32 | "platformType", 33 | "Linux" 34 | ] 35 | }, 36 | "action": "aws:runShellScript", 37 | "name": "runInSpecLinux", 38 | "inputs": { 39 | "runCommand": [ 40 | "#!/bin/bash", 41 | "if ! which curl &> /dev/null; then", 42 | " echo 'curl is missing from the instance! Exiting.'", 43 | " exit 1", 44 | "fi", 45 | "region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\\(.*\\)[a-z]/\\1/')", 46 | "complianceFile='report_compliance'", 47 | "scriptFile='run_inspec.sh'", 48 | "if [[ $region == cn-* ]] ; then", 49 | " s3Prefix='https://s3.'", 50 | " s3Suffix='.cn'", 51 | "elif [[ $region == us-gov* ]] ; then", 52 | " s3Prefix='https://s3-fips-'", 53 | " s3Suffix=''", 54 | "else", 55 | " s3Prefix='https://s3.dualstack.'", 56 | " s3Suffix=''", 57 | "fi", 58 | "curl -sS ${s3Prefix}${region}.amazonaws.com${s3Suffix}/aws-ssm-${region}/inspec/${complianceFile} -o ${complianceFile}", 59 | "if [ $? -ne 0 ] ; then", 60 | " echo 'Failed to download inspec compliance file from S3. Exiting.'", 61 | " exit 1", 62 | "fi", 63 | "curl -sS ${s3Prefix}${region}.amazonaws.com${s3Suffix}/aws-ssm-${region}/inspec/${scriptFile} -o ${scriptFile}", 64 | "if [ $? -ne 0 ] ; then", 65 | " echo 'Failed to download inspec script file from S3. Exiting.'", 66 | " exit 1", 67 | "fi", 68 | "bash ./${scriptFile}", 69 | "if [ $? -ne 0 ] ; then", 70 | " echo 'Failed to run Inspec checks. Exiting.'", 71 | " exit 1", 72 | "fi" 73 | ] 74 | } 75 | }, 76 | { 77 | "precondition": { 78 | "StringEquals": [ 79 | "platformType", 80 | "Windows" 81 | ] 82 | }, 83 | "action": "aws:runPowerShellScript", 84 | "name": "runInSpecWindows", 85 | "inputs": { 86 | "runCommand": [ 87 | "$s3FilePath = 'inspec/'", 88 | "$s3ComplianceFile = 'report_compliance'", 89 | "$s3ScriptFile = 'run_inspec.ps1'", 90 | "$scriptLocalPath = $s3ScriptFile", 91 | "$curDirectory = Convert-Path .", 92 | "$env:PATH += \";$curDirectory\"", 93 | "", 94 | "function GetS3DownloadUrl ([string]$appPath, [string]$fileVersion) {", 95 | " $region = $env:AWS_SSM_REGION_NAME", 96 | "", 97 | " if ($region.StartsWith('cn-')) {", 98 | " # China endpoint", 99 | " $s3PrefixUrl = 'https://s3.{0}.amazonaws.com.cn/aws-ssm-{0}/'", 100 | " } elseif ($region.StartsWith('us-gov')) {", 101 | " # GovCloud endpoint", 102 | " $s3PrefixUrl = 'https://s3-fips-{0}.amazonaws.com/aws-ssm-{0}/'", 103 | " } else {", 104 | " # Public AWS endpoint", 105 | " $s3PrefixUrl = 'https://s3.dualstack.{0}.amazonaws.com/aws-ssm-{0}/'", 106 | " }", 107 | "", 108 | " $s3Location = ($s3PrefixUrl + $appPath + $fileVersion) -f $region", 109 | " $s3Location", 110 | "}", 111 | "", 112 | "$s3Location = GetS3DownloadUrl $s3FilePath $s3ComplianceFile", 113 | "Start-BitsTransfer -Source $s3Location -Destination $s3ComplianceFile", 114 | "$s3Location = GetS3DownloadUrl $s3FilePath $s3ScriptFile", 115 | "Start-BitsTransfer -Source $s3Location -Destination $scriptLocalPath", 116 | "", 117 | "iex $scriptLocalPath", 118 | "if ($?) {", 119 | " exit $LASTEXITCODE", 120 | "} else {", 121 | " exit 255", 122 | "}" 123 | ] 124 | } 125 | } 126 | ] 127 | } 128 | -------------------------------------------------------------------------------- /documents/AWS-RunPowerShellScript: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Run a PowerShell script or specify the paths to scripts to run.", 4 | "parameters": { 5 | "commands": { 6 | "type": "StringList", 7 | "description": "(Required) Specify the commands to run or the paths to existing scripts on the instance.", 8 | "minItems": 1, 9 | "displayType": "textarea" 10 | }, 11 | "workingDirectory": { 12 | "type": "String", 13 | "default": "", 14 | "description": "(Optional) The path to the working directory on your instance.", 15 | "maxChars": 4096 16 | }, 17 | "executionTimeout": { 18 | "type": "String", 19 | "default": "3600", 20 | "description": "(Optional) The time in seconds for a command to be completed before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).", 21 | "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)" 22 | } 23 | }, 24 | "runtimeConfig": { 25 | "aws:runPowerShellScript": { 26 | "properties": [ 27 | { 28 | "id": "0.aws:runPowerShellScript", 29 | "runCommand": "{{ commands }}", 30 | "workingDirectory": "{{ workingDirectory }}", 31 | "timeoutSeconds": "{{ executionTimeout }}" 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /documents/AWS-RunRemoteScript: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Execute scripts stored in a remote location. The following remote locations are currently supported: GitHub (public and private) and Amazon S3 (S3). The following script types are currently supported: #! support on Linux and file associations on Windows.", 4 | "parameters": { 5 | "sourceType": { 6 | "description": "(Required) Specify the source type.", 7 | "type": "String", 8 | "allowedValues": [ 9 | "GitHub", 10 | "S3" 11 | ] 12 | }, 13 | "sourceInfo": { 14 | "description": "(Required) Specify the information required to access the resource from the source. If source type is GitHub, then you can specify any of the following: 'owner', 'repository', 'path', 'getOptions', 'tokenInfo'. If source type is S3, then you can specify 'path'.", 15 | "type": "StringMap", 16 | "displayType": "textarea", 17 | "default": {} 18 | }, 19 | "commandLine": { 20 | "description": "(Required) Specify the command line to be executed. The following formats of commands can be run: 'pythonMainFile.py argument1 argument2', 'ansible-playbook -i \"localhost,\" -c local example.yml'", 21 | "type": "String", 22 | "default": "" 23 | }, 24 | "workingDirectory": { 25 | "type": "String", 26 | "default": "", 27 | "description": "(Optional) The path where the content will be downloaded and executed from on your instance.", 28 | "maxChars": 4096 29 | }, 30 | "executionTimeout": { 31 | "description": "(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 28800 (8 hours).", 32 | "type": "String", 33 | "default": "3600", 34 | "allowedPattern": "([1-9][0-9]{0,3})|(1[0-9]{1,4})|(2[0-7][0-9]{1,3})|(28[0-7][0-9]{1,2})|(28800)" 35 | } 36 | }, 37 | "mainSteps": [ 38 | { 39 | "action": "aws:downloadContent", 40 | "name": "downloadContent", 41 | "inputs": { 42 | "sourceType": "{{ sourceType }}", 43 | "sourceInfo": "{{ sourceInfo }}", 44 | "destinationPath": "{{ workingDirectory }}" 45 | } 46 | }, 47 | { 48 | "precondition": { 49 | "StringEquals": [ 50 | "platformType", 51 | "Windows" 52 | ] 53 | }, 54 | "action": "aws:runPowerShellScript", 55 | "name": "runPowerShellScript", 56 | "inputs": { 57 | "runCommand": [ 58 | "", 59 | "$directory = Convert-Path .", 60 | "$env:PATH += \";$directory\"", 61 | " {{ commandLine }}", 62 | "if ($?) {", 63 | " exit $LASTEXITCODE", 64 | "} else {", 65 | " exit 255", 66 | "}", 67 | "" 68 | ], 69 | "workingDirectory": "{{ workingDirectory }}", 70 | "timeoutSeconds": "{{ executionTimeout }}" 71 | } 72 | }, 73 | { 74 | "precondition": { 75 | "StringEquals": [ 76 | "platformType", 77 | "Linux" 78 | ] 79 | }, 80 | "action": "aws:runShellScript", 81 | "name": "runShellScript", 82 | "inputs": { 83 | "runCommand": [ 84 | "", 85 | "directory=$(pwd)", 86 | "export PATH=$PATH:$directory", 87 | " {{ commandLine }} ", 88 | "" 89 | ], 90 | "workingDirectory": "{{ workingDirectory }}", 91 | "timeoutSeconds": "{{ executionTimeout }}" 92 | } 93 | } 94 | ] 95 | } 96 | -------------------------------------------------------------------------------- /documents/AWS-RunSaltState: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.0", 3 | "description": "Use this document to run Salt States on Amazon EC2 managed instances. Specify either YAML text or the URL to download a YAML file containing the state. If you specify both, the URL parameter will be used.", 4 | "parameters": { 5 | "state": { 6 | "type": "String", 7 | "description": "(Optional) If you don't specify a URL, then you must specify the State YAML in this field.", 8 | "default": "", 9 | "displayType": "textarea" 10 | }, 11 | "stateurl": { 12 | "type": "String", 13 | "description": "(Optional) If you don't specify YAML, then you must specify a URL where the state file is stored. You can specify the URL in the following formats: http://example.com/state.sls or s3://examplebucket/state.sls. For security reasons, you can't specify a URL with quotes.", 14 | "default": "", 15 | "allowedPattern": "^\\s*$|^(http|https|s3)://[^']*$" 16 | }, 17 | "pillars": { 18 | "type": "String", 19 | "description": "(Optional) Additional variables to pass to Salt at runtime. They must be entered in the format '{\"test1\":\"value1\", \"test2\":\"value2\"}'", 20 | "default": "{\"SSM\":\"True\"}", 21 | "displayType": "textarea" 22 | }, 23 | "test": { 24 | "type": "String", 25 | "description": " (Optional) Use the test parameter to perform a dry run of the Salt execution.", 26 | "allowedValues": [ 27 | "True", 28 | "False" 29 | ], 30 | "default": "False" 31 | } 32 | }, 33 | "mainSteps": [ 34 | { 35 | "action": "aws:runShellScript", 36 | "name": "runShellScript", 37 | "inputs": { 38 | "runCommand": [ 39 | "#!/bin/bash", 40 | "salt-call --version", 41 | "if [ $? -ne 0 ]; then", 42 | " echo \"Salt is not installed. Please install Salt and rerun the command\" >&2", 43 | " exit 1", 44 | "fi", 45 | "sudo mkdir -p /srv/salt", 46 | "if [ -z \"{{state}}\" ] ; then", 47 | " if [[ \"{{stateurl}}\" == http* ]]; then", 48 | " wget '{{stateurl}}' -O /srv/salt/state.sls", 49 | " if [ $? -ne 0 ]; then", 50 | " echo \"There was a problem downloading the salt state file. Make sure the URL is correct and that the state file exists.\" >&2", 51 | " exit 1", 52 | " fi", 53 | " elif [[ \"{{stateurl}}\" == s3* ]] ; then", 54 | " aws --version", 55 | " if [ $? -ne 0 ]; then", 56 | " echo \"The AWS CLI is not installed. The CLI is required to process Amazon S3 URLs. Install the AWS CLI and run the command again.\" >&2", 57 | " exit 1", 58 | " fi", 59 | " aws s3 cp '{{stateurl}}' /srv/salt/state.sls", 60 | " else", 61 | " echo \"The salt state file URL is not valid. Verify the URL and try again. \"", 62 | " exit 1", 63 | " fi", 64 | "else", 65 | " echo \"{{state}}\" > /srv/salt/state.sls", 66 | "fi", 67 | "if [[ \"{{test}}\" == True ]] ; then", 68 | " sudo salt-call --local state.apply state test=True pillar='{{pillars}}'", 69 | " if [ $? -ne 0 ]; then", 70 | " exit 1", 71 | " fi", 72 | "else", 73 | " sudo salt-call --local state.apply state pillar='{{pillars}}'", 74 | " if [ $? -ne 0 ]; then", 75 | " exit 1", 76 | " fi", 77 | "fi", 78 | "rm -f /srv/salt/state.sls" 79 | ] 80 | } 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /documents/AWS-RunShellScript: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Run a shell script or specify the commands to run.", 4 | "parameters": { 5 | "commands": { 6 | "type": "StringList", 7 | "description": "(Required) Specify a shell script or a command to run.", 8 | "minItems": 1, 9 | "displayType": "textarea" 10 | }, 11 | "workingDirectory": { 12 | "type": "String", 13 | "default": "", 14 | "description": "(Optional) The path to the working directory on your instance.", 15 | "maxChars": 4096 16 | }, 17 | "executionTimeout": { 18 | "type": "String", 19 | "default": "3600", 20 | "description": "(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).", 21 | "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)" 22 | } 23 | }, 24 | "runtimeConfig": { 25 | "aws:runShellScript": { 26 | "properties": [ 27 | { 28 | "id": "0.aws:runShellScript", 29 | "runCommand": "{{ commands }}", 30 | "workingDirectory": "{{ workingDirectory }}", 31 | "timeoutSeconds": "{{ executionTimeout }}" 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /documents/AWS-SetupManagedInstance: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Manage EC2 instance", 3 | "schemaVersion": "0.3", 4 | "assumeRole": "{{AutomationAssumeRole}}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) EC2 InstanceId to manage" 9 | }, 10 | "RoleName": { 11 | "type": "String", 12 | "description": "(Optional) The name of the IAM Role for the EC2 Instance. If this Role does not exist, it will be created. When specifying this value, the caller should ensure the Role contains the AWS Managed Policy \"AmazonEC2RoleForSsm\".", 13 | "default": "SSMRoleForManagedInstance" 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 | "LambdaAssumeRole": { 21 | "type": "String", 22 | "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.", 23 | "default": "" 24 | } 25 | }, 26 | "mainSteps": [ 27 | { 28 | "name": "setupManagedRole", 29 | "action": "aws:executeAutomation", 30 | "onFailure": "Abort", 31 | "inputs": { 32 | "DocumentName": "AWS-SetupManagedRoleOnEc2Instance", 33 | "RuntimeParameters": { 34 | "InstanceId": [ 35 | "{{InstanceId}}" 36 | ], 37 | "RoleName": [ 38 | "{{RoleName}}" 39 | ], 40 | "LambdaAssumeRole": [ 41 | "{{LambdaAssumeRole}}" 42 | ], 43 | "AutomationAssumeRole": [ 44 | "{{AutomationAssumeRole}}" 45 | ] 46 | } 47 | } 48 | }, 49 | { 50 | "name": "updateSsmAgent", 51 | "action": "aws:runCommand", 52 | "maxAttempts": 1, 53 | "onFailure": "Abort", 54 | "inputs": { 55 | "DocumentName": "AWS-UpdateSSMAgent", 56 | "InstanceIds": [ 57 | "{{InstanceId}}" 58 | ] 59 | } 60 | }, 61 | { 62 | "name": "configureCloudWatch", 63 | "action": "aws:executeAutomation", 64 | "onFailure": "Abort", 65 | "inputs": { 66 | "DocumentName": "AWS-ConfigureCloudWatchOnEC2Instance", 67 | "RuntimeParameters": { 68 | "InstanceId": [ 69 | "{{InstanceId}}" 70 | ], 71 | "LambdaAssumeRole": [ 72 | "{{LambdaAssumeRole}}" 73 | ], 74 | "AutomationAssumeRole": [ 75 | "{{AutomationAssumeRole}}" 76 | ] 77 | } 78 | } 79 | } 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /documents/AWS-StartEC2Instance: -------------------------------------------------------------------------------- 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/AWS-StartEC2InstanceWithApproval: -------------------------------------------------------------------------------- 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/AWS-StartPortForwardingSession: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.0", 3 | "description": "Document to start port forwarding session over Session Manager", 4 | "sessionType": "Port", 5 | "parameters": { 6 | "portNumber": { 7 | "type": "String", 8 | "description": "(Optional) Port number of the server on the instance", 9 | "allowedPattern": "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", 10 | "default": "80" 11 | }, 12 | "localPortNumber": { 13 | "type": "String", 14 | "description": "(Optional) Port number on local machine to forward traffic to. An open port is chosen at run-time if not provided", 15 | "allowedPattern": "^([0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", 16 | "default": "0" 17 | } 18 | }, 19 | "properties": { 20 | "portNumber": "{{ portNumber }}", 21 | "type": "LocalPortForwarding", 22 | "localPortNumber": "{{ localPortNumber }}" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /documents/AWS-StartRdsInstance: -------------------------------------------------------------------------------- 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 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "AssertNotStartingOrAvailable", 19 | "action": "aws:assertAwsResourceProperty", 20 | "isCritical": false, 21 | "onFailure": "step:StartInstance", 22 | "nextStep": "CheckStart", 23 | "inputs": { 24 | "Service": "rds", 25 | "Api": "DescribeDBInstances", 26 | "DBInstanceIdentifier": "{{InstanceId}}", 27 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 28 | "DesiredValues": [ 29 | "available", 30 | "starting" 31 | ] 32 | } 33 | }, 34 | { 35 | "name": "StartInstance", 36 | "action": "aws:executeAwsApi", 37 | "inputs": { 38 | "Service": "rds", 39 | "Api": "StartDBInstance", 40 | "DBInstanceIdentifier": "{{InstanceId}}" 41 | } 42 | }, 43 | { 44 | "name": "CheckStart", 45 | "action": "aws:waitForAwsResourceProperty", 46 | "onFailure": "Abort", 47 | "maxAttempts": 10, 48 | "timeoutSeconds": 600, 49 | "inputs": { 50 | "Service": "rds", 51 | "Api": "DescribeDBInstances", 52 | "DBInstanceIdentifier": "{{InstanceId}}", 53 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 54 | "DesiredValues": [ 55 | "available" 56 | ] 57 | }, 58 | "isEnd": true 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /documents/AWS-StartSSHSession: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.0", 3 | "description": "Document to open SSH connection over session manager to an instance", 4 | "sessionType": "Port", 5 | "parameters": { 6 | "portNumber": { 7 | "type": "String", 8 | "description": "(Optional) Port number of SSH server on the instance", 9 | "allowedPattern": "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", 10 | "default": "22" 11 | } 12 | }, 13 | "properties": { 14 | "portNumber": "{{ portNumber }}" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /documents/AWS-StopEC2Instance: -------------------------------------------------------------------------------- 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/AWS-StopEC2InstanceWithApproval: -------------------------------------------------------------------------------- 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 | "inputs": { 40 | "InstanceIds": "{{ InstanceId }}", 41 | "DesiredState": "stopped" 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /documents/AWS-StopRdsInstance: -------------------------------------------------------------------------------- 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 | }, 16 | "mainSteps": [ 17 | { 18 | "name": "AssertNotStopped", 19 | "action": "aws:assertAwsResourceProperty", 20 | "isCritical": false, 21 | "onFailure": "step:StopInstance", 22 | "nextStep": "CheckStop", 23 | "inputs": { 24 | "Service": "rds", 25 | "Api": "DescribeDBInstances", 26 | "DBInstanceIdentifier": "{{InstanceId}}", 27 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 28 | "DesiredValues": [ 29 | "stopped", 30 | "stopping" 31 | ] 32 | } 33 | }, 34 | { 35 | "name": "StopInstance", 36 | "action": "aws:executeAwsApi", 37 | "inputs": { 38 | "Service": "rds", 39 | "Api": "StopDBInstance", 40 | "DBInstanceIdentifier": "{{InstanceId}}" 41 | } 42 | }, 43 | { 44 | "name": "CheckStop", 45 | "action": "aws:waitForAwsResourceProperty", 46 | "onFailure": "Abort", 47 | "maxAttempts": 10, 48 | "timeoutSeconds": 600, 49 | "inputs": { 50 | "Service": "rds", 51 | "Api": "DescribeDBInstances", 52 | "DBInstanceIdentifier": "{{InstanceId}}", 53 | "PropertySelector": "$.DBInstances[0].DBInstanceStatus", 54 | "DesiredValues": [ 55 | "stopped" 56 | ] 57 | } 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /documents/AWS-TerminateEC2Instance: -------------------------------------------------------------------------------- 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/AWS-TerminateEC2InstanceWithApproval: -------------------------------------------------------------------------------- 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/AWS-UpdateCloudFormationStack: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Update Cloud Formation Stack using cloud formation template from a S3 bucket.", 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 | "default": "", 20 | "type": "String", 21 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. " 22 | } 23 | }, 24 | "mainSteps": [ 25 | { 26 | "action": "aws:createStack", 27 | "inputs": { 28 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}", 29 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\nResources:\n UpdateCFLambda:\n Properties:\n Code: {ZipFile: \"import boto3\\n\\n\\ndef handler(event, context):\\n\\tcf = boto3.client(\\\"\\\n cloudformation\\\")\\n\\n\\tcf.update_stack(\\n\\t\\tStackName=event[\\\"StackName\\\"\\\n ],\\n\\t\\tTemplateURL=event[\\\"TemplateUrl\\\"],\\n\\t\\tCapabilities=[\\\"CAPABILITY_IAM\\\"\\\n ]\\n\\t)\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role: {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n", 30 | "Parameters": [ 31 | { 32 | "ParameterValue": "{{LambdaAssumeRole}}", 33 | "ParameterKey": "LambdaRoleArn" 34 | }, 35 | { 36 | "ParameterValue": "UpdateCFTemplate-{{automation:EXECUTION_ID}}", 37 | "ParameterKey": "LambdaName" 38 | } 39 | ], 40 | "Capabilities": [ 41 | "CAPABILITY_IAM" 42 | ] 43 | }, 44 | "name": "createDocumentStack" 45 | }, 46 | { 47 | "action": "aws:invokeLambdaFunction", 48 | "inputs": { 49 | "FunctionName": "UpdateCFTemplate-{{automation:EXECUTION_ID}}", 50 | "Payload": "{\"StackName\": \"{{StackNameOrId}}\", \"TemplateUrl\": \"{{TemplateUrl}}\"}" 51 | }, 52 | "name": "updateCloudFormationTemplate" 53 | }, 54 | { 55 | "action": "aws:deleteStack", 56 | "inputs": { 57 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}" 58 | }, 59 | "name": "deleteCloudFormationTemplate" 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /documents/AWS-UpdateCloudFormationStackWithApproval: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "assumeRole": "{{AutomationAssumeRole}}", 4 | "description": "Update Cloud Formation Stack with Approval using cloud formation template from a S3 bucket.", 5 | "parameters": { 6 | "LambdaAssumeRole": { 7 | "type": "String", 8 | "description": "(Required) The ARN of the role assumed by lambda" 9 | }, 10 | "SNSTopicArn": { 11 | "type": "String", 12 | "description": "(Required) The SNS topic ARN used to send pending approval notification for updating CloudFormation Template. The SNS topic name must start with Automation." 13 | }, 14 | "StackNameOrId": { 15 | "type": "String", 16 | "description": "(Required) Name or Unique ID of the CloudFormation stack to be updated" 17 | }, 18 | "Approvers": { 19 | "type": "StringList", 20 | "description": "(Required) IAM user or user arn of approvers for the automation action" 21 | }, 22 | "TemplateUrl": { 23 | "type": "String", 24 | "description": "(Required) S3 bucket location of updated CloudFormation Template (e.g. https://s3.amazonaws.com/example/updated.template)" 25 | }, 26 | "AutomationAssumeRole": { 27 | "default": "", 28 | "type": "String", 29 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. " 30 | } 31 | }, 32 | "mainSteps": [ 33 | { 34 | "action": "aws:approve", 35 | "inputs": { 36 | "NotificationArn": "{{SNSTopicArn}}", 37 | "Message": "Approval required to update CloudFormation stack: {{StackNameOrId}}", 38 | "Approvers": "{{Approvers}}", 39 | "MinRequiredApprovals": 1 40 | }, 41 | "name": "approve", 42 | "onFailure": "Abort" 43 | }, 44 | { 45 | "action": "aws:createStack", 46 | "inputs": { 47 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}", 48 | "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nParameters:\n LambdaName: {Description: 'The lambda function name\n\n ', Type: String}\n LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n created by Automation to perform the action on your behalf\n\n ', Type: String}\nResources:\n UpdateCFLambda:\n Properties:\n Code: {ZipFile: \"import boto3\\n\\n\\ndef handler(event, context):\\n\\tcf = boto3.client(\\\"\\\n cloudformation\\\")\\n\\n\\tcf.update_stack(\\n\\t\\tStackName=event[\\\"StackName\\\"\\\n ],\\n\\t\\tTemplateURL=event[\\\"TemplateUrl\\\"],\\n\\t\\tCapabilities=[\\\"CAPABILITY_IAM\\\"\\\n ]\\n\\t)\\n\"}\n FunctionName: {Ref: LambdaName}\n Handler: index.handler\n MemorySize: 128\n Role: {Ref: LambdaRoleArn}\n Runtime: python2.7\n Timeout: 60\n Type: AWS::Lambda::Function\n", 49 | "Parameters": [ 50 | { 51 | "ParameterValue": "{{LambdaAssumeRole}}", 52 | "ParameterKey": "LambdaRoleArn" 53 | }, 54 | { 55 | "ParameterValue": "UpdateCFTemplate-{{automation:EXECUTION_ID}}", 56 | "ParameterKey": "LambdaName" 57 | } 58 | ], 59 | "Capabilities": [ 60 | "CAPABILITY_IAM" 61 | ] 62 | }, 63 | "name": "createDocumentStack" 64 | }, 65 | { 66 | "action": "aws:invokeLambdaFunction", 67 | "inputs": { 68 | "FunctionName": "UpdateCFTemplate-{{automation:EXECUTION_ID}}", 69 | "Payload": "{\"StackName\": \"{{StackNameOrId}}\", \"TemplateUrl\": \"{{TemplateUrl}}\"}" 70 | }, 71 | "name": "updateCloudFormationTemplate" 72 | }, 73 | { 74 | "action": "aws:deleteStack", 75 | "inputs": { 76 | "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}" 77 | }, 78 | "name": "deleteCloudFormationTemplate" 79 | } 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /documents/AWS-UpdateEC2Config: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Update the EC2Config service to the latest version or specify an older version.", 4 | "parameters": { 5 | "version": { 6 | "default": "", 7 | "description": "(Optional) A specific version of the EC2Config service to install. If not specified, the service will be updated to the latest version.", 8 | "type": "String" 9 | }, 10 | "allowDowngrade": { 11 | "default": "false", 12 | "description": "(Optional) Allow the EC2Config service to be downgraded to an earlier version. If set to false, the service can be upgraded to newer versions only (default). If set to true, specify the earlier version.", 13 | "type": "String", 14 | "allowedValues": [ 15 | "true", 16 | "false" 17 | ] 18 | } 19 | }, 20 | "runtimeConfig": { 21 | "aws:updateAgent": { 22 | "properties": { 23 | "agentName": "Ec2Config", 24 | "source": "https://s3.us-east-1.amazonaws.com/aws-ssm-us-east-1/manifest.json", 25 | "allowDowngrade": "{{ allowDowngrade }}", 26 | "targetVersion": "{{ version }}" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /documents/AWS-UpdateSSMAgent: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.2", 3 | "description": "Update the Amazon SSM Agent to the latest version or specified version.", 4 | "parameters": { 5 | "version": { 6 | "default": "", 7 | "description": "(Optional) A specific version of the Amazon SSM Agent to install. If not specified, the agent will be updated to the latest version.", 8 | "type": "String" 9 | }, 10 | "allowDowngrade": { 11 | "default": "false", 12 | "description": "(Optional) Allow the Amazon SSM Agent service to be downgraded to an earlier version. If set to false, the service can be upgraded to newer versions only (default). If set to true, specify the earlier version.", 13 | "type": "String", 14 | "allowedValues": [ 15 | "true", 16 | "false" 17 | ] 18 | } 19 | }, 20 | "runtimeConfig": { 21 | "aws:updateSsmAgent": { 22 | "properties": [ 23 | { 24 | "agentName": "amazon-ssm-agent", 25 | "source": "https://s3.{Region}.amazonaws.com/amazon-ssm-{Region}/ssm-agent-manifest.json", 26 | "allowDowngrade": "{{ allowDowngrade }}", 27 | "targetVersion": "{{ version }}" 28 | } 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /documents/AWSEC2-ApplicationInsightsCloudwatchAgentInstallAndConfigure: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "A composite document for installing and configuring CloudWatchAgent.", 4 | "parameters": { 5 | "parameterStoreName": { 6 | "description": "(Required) The value is the ssm parameter store name for ssm config source.", 7 | "type": "String", 8 | "allowedPattern": "[^\"]*" 9 | } 10 | }, 11 | "mainSteps": [ 12 | { 13 | "action": "aws:configurePackage", 14 | "name": "configurePackage", 15 | "inputs": { 16 | "name": "AmazonCloudWatchAgent", 17 | "action": "Install" 18 | } 19 | }, 20 | { 21 | "action": "aws:runDocument", 22 | "name": "configureCWAgent", 23 | "inputs": { 24 | "documentType": "SSMDocument", 25 | "documentPath": "AmazonCloudWatch-ManageAgent", 26 | "documentParameters": "{\"action\":\"configure (append)\",\"mode\" : \"ec2\",\"optionalConfigurationSource\" : \"ssm\",\"optionalConfigurationLocation\" : {{parameterStoreName}}}" 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /documents/AWSEC2-RunSysprep: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Performs sysprep on Windows Server 2008 SP2 and above. Does not shutdown the instance.", 4 | "parameters": { 5 | "Id": { 6 | "type": "String", 7 | "description": "(Optional) A user specified ID for the execution of sysprep.", 8 | "default": "" 9 | } 10 | }, 11 | "mainSteps": [ 12 | { 13 | "action": "aws:runPowerShellScript", 14 | "name": "RunSysprep", 15 | "precondition": { 16 | "StringEquals": [ 17 | "platformType", 18 | "Windows" 19 | ] 20 | }, 21 | "inputs": { 22 | "timeoutSeconds": 14400, 23 | "runCommand": [ 24 | "", 25 | "$zipFilename = 'AWSUpdateWindowsInstance_1_4_4_0.zip'", 26 | "$zipFileHash = 'CD337ADCFBA463DE895B8D8248A3991940ABB03ADF8525ECA1302385D6A1DDA6'", 27 | "$moduleName = 'AWSUpdateWindowsInstance'", 28 | "$tempPath = $env:TEMP", 29 | "$moduleDirectory = Join-Path $tempPath -ChildPath $moduleName", 30 | "$moduleZipFilePath = Join-Path $tempPath -ChildPath $zipFilename", 31 | "$moduleManifestPath = Join-Path $moduleDirectory -ChildPath ('{0}.psd1' -f $moduleName)", 32 | "$id = '{{Id}}'", 33 | "", 34 | "function Main {", 35 | " Test-PreCondition", 36 | " Clear-WindowsUpdateModule", 37 | " Get-WindowsUpdateModule", 38 | " Expand-WindowsUpdateModule", 39 | " Invoke-RunSysprep", 40 | "}", 41 | "function Test-PreCondition {", 42 | " $osversion = [Environment]::OSVersion.Version", 43 | " if ($osversion.Major -le 5) {", 44 | " Write-Host 'This document is not supported on Windows Server 2003 or earlier.'", 45 | " Exit -1", 46 | " }", 47 | "", 48 | " if ($osversion.Version -ge '10.0') {", 49 | " $sku = (Get-CimInstance -ClassName Win32_OperatingSystem).OperatingSystemSKU", 50 | " if ($sku -eq 143 -or $sku -eq 144) {", 51 | " Write-Host 'This document is not supported on Windows 2016 Nano Server.'", 52 | " Exit -1", 53 | " }", 54 | " }", 55 | "}", 56 | "", 57 | "function Clear-WindowsUpdateModule {", 58 | " try {", 59 | " if (Test-Path $moduleDirectory) {", 60 | " Remove-Item $moduleDirectory -Force -Recurse", 61 | " }", 62 | " if (Test-Path $moduleZipFilePath) {", 63 | " Remove-Item $moduleZipFilePath -Force", 64 | " }", 65 | " } catch {", 66 | " Write-Host \"Cleaning Windows update module resulted in error: $($_)\"", 67 | " }", 68 | "}", 69 | "", 70 | "function Get-WindowsUpdateModule {", 71 | " try {", 72 | " $ssmAgentService = Get-ItemProperty 'HKLM:SYSTEM\\CurrentControlSet\\Services\\AmazonSSMAgent\\' -ErrorAction SilentlyContinue", 73 | " if($ssmAgentService -and $ssmAgentService.Version -ge '2.0.533.0') {", 74 | " $region = $env:AWS_SSM_REGION_NAME", 75 | " }", 76 | "", 77 | " if(-not $region) {", 78 | " try {", 79 | " $identityDocumentUrl = 'http://169.254.169.254/latest/dynamic/instance-identity/document'", 80 | " $region = ((Invoke-WebRequest -UseBasicParsing -uri $identityDocumentUrl).Content | ConvertFrom-Json).region", 81 | " } catch {", 82 | " $region = 'us-east-1'", 83 | " }", 84 | " }", 85 | "", 86 | "", 87 | " if ($region.StartsWith('cn-')) {", 88 | " $s3Location = 'https://s3.{0}.amazonaws.com.cn/aws-windows-downloads-{0}/PSModules/AWSUpdateWindowsInstance/{1}'", 89 | " } elseif($region.StartsWith('us-gov-')) {", 90 | " $s3Location = 'https://s3-fips-{0}.amazonaws.com/aws-windows-downloads-{0}/PSModules/AWSUpdateWindowsInstance/{1}'", 91 | " } elseif($region -eq 'us-east-1') {", 92 | " $s3Location = 'https://s3.amazonaws.com/aws-windows-downloads-{0}/PSModules/AWSUpdateWindowsInstance/{1}'", 93 | " } else {", 94 | " $s3Location = 'https://aws-windows-downloads-{0}.s3.amazonaws.com/PSModules/AWSUpdateWindowsInstance/{1}'", 95 | " }", 96 | "", 97 | " $source = $s3Location -f $region, $zipFilename", 98 | " $moduleLocalPath = Join-Path $tempPath -ChildPath $zipFilename", 99 | " Start-BitsTransfer -Source $source -Destination $moduleLocalPath", 100 | "", 101 | " $fileStream = New-Object System.IO.FileStream($moduleLocalPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)", 102 | " $sha256 = [System.Security.Cryptography.HashAlgorithm]::Create('System.Security.Cryptography.SHA256CryptoServiceProvider')", 103 | " $currentHash = [System.BitConverter]::ToString($sha256.ComputeHash($fileStream), 0).Replace('-', '').ToLowerInvariant()", 104 | " $sha256.Dispose()", 105 | " $fileStream.Dispose()", 106 | "", 107 | " if ($currentHash -ne $zipFileHash) {", 108 | " Write-Host 'The SHA hash of the module does not match the expected value.'", 109 | " Exit -1", 110 | " }", 111 | " } catch {", 112 | " Write-Host ('Error encountered while getting the module: {0}.' -f $_.Exception.Message)", 113 | " Exit -1", 114 | " }", 115 | "}", 116 | "", 117 | "function Expand-WindowsUpdateModule {", 118 | " try {", 119 | " [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null", 120 | " $zip = [System.IO.Compression.ZipFile]::OpenRead($moduleZipFilePath)", 121 | " foreach ($item in $zip.Entries) {", 122 | " $extractPath = Join-Path $tempPath -ChildPath $item.FullName", 123 | " if ($item.Length -eq 0) {", 124 | " if (-not (Test-Path $extractPath)) {", 125 | " New-Item $extractPath -ItemType Directory | Out-Null", 126 | " }", 127 | " } else {", 128 | " $parentPath = Split-Path $extractPath", 129 | " if (-not (Test-Path $parentPath)) {", 130 | " New-Item $parentPath -ItemType Directory | Out-Null", 131 | " }", 132 | " [System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $extractPath, $true)", 133 | " }", 134 | " }", 135 | " } catch {", 136 | " Write-Host ('Error encountered when extracting module file: {0}.' -f $_.Exception.Message)", 137 | " Exit -1", 138 | " } finally {", 139 | " $zip.Dispose()", 140 | " }", 141 | "}", 142 | "", 143 | "function Invoke-RunSysprep {", 144 | " Import-Module $moduleManifestPath", 145 | " $command = 'Start-AwsUwiSysprep'", 146 | " if($id) { $command += \" -Id $($id)\"}", 147 | " Invoke-Expression $command", 148 | "}", 149 | "", 150 | "Main" 151 | ] 152 | } 153 | } 154 | ] 155 | } 156 | -------------------------------------------------------------------------------- /documents/AWSSupport-GrantPermissionsToIAMUser: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "This document grants the specified permissions to an IAM group (new or existing), and adds the existing IAM user to it. Policies you can choose from: Billing (https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/job-function/Billing$serviceLevelSummary), Support (https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AWSSupportAccess$serviceLevelSummary). To enable billing access for IAM, remember to also activate *IAM user and federated user access to the Billing and Cost Management pages*: http://docs.aws.amazon.com/console/iam/billing-enable. WARNING: If you provide an existing IAM group, all current IAM users in the group receive the new permissions.", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "IAMGroupName": { 7 | "type": "String", 8 | "description": "(Required) Can be a new or existing group. Must comply with https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-names.", 9 | "default": "ExampleSupportAndBillingGroup", 10 | "allowedPattern": "^[a-zA-Z0-9+=,.@_-]{1,128}$" 11 | }, 12 | "IAMUserName": { 13 | "type": "String", 14 | "description": "(Required) Must be an existing user.", 15 | "default": "ExampleUser", 16 | "allowedPattern": "^[a-zA-Z0-9+=,.@_-]{1,64}" 17 | }, 18 | "Permissions": { 19 | "type": "String", 20 | "description": "(Required) Choose one of: SupportFullAccess - Grants full access to the Support center | BillingFullAccess - Grants full access to the Billing dashboard | SupportAndBillingFullAccess - Grants full access to both Support center and the Billing dashboard. More info on policies under Document details.", 21 | "default": "SupportAndBillingFullAccess", 22 | "allowedValues": [ 23 | "SupportFullAccess", 24 | "BillingFullAccess", 25 | "SupportAndBillingFullAccess" 26 | ] 27 | }, 28 | "LambdaAssumeRole": { 29 | "type": "String", 30 | "description": "(Optional) The ARN of the role assumed by lambda.", 31 | "default": "" 32 | }, 33 | "AutomationAssumeRole": { 34 | "type": "String", 35 | "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, AWS Systems Manager Automation will use the permissions of the user that executes this document.", 36 | "default": "" 37 | } 38 | }, 39 | "mainSteps": [ 40 | { 41 | "name": "createDocumentStack", 42 | "action": "aws:createStack", 43 | "inputs": { 44 | "StackName": "AWSSupport-GrantPermissionsToIAMUser-{{ automation:EXECUTION_ID }}", 45 | "OnFailure": "DELETE", 46 | "TemplateURL": "https://awssupport-ssm.{{ global:REGION }}.s3.amazonaws.com/AWSSupport-GrantPermissionsToIAMUser/CloudFormationTemplates/AWSSupport-GrantPermissionsToIAMUser_va9fa140c79359997d1506c5ca8eb7b84543c8502.template", 47 | "Capabilities": [ 48 | "CAPABILITY_IAM" 49 | ], 50 | "Parameters": [ 51 | { 52 | "ParameterKey": "LambdaName", 53 | "ParameterValue": "AWSSupport-ConfigureIAM-{{ automation:EXECUTION_ID }}" 54 | }, 55 | { 56 | "ParameterKey": "LambdaRoleArn", 57 | "ParameterValue": "{{ LambdaAssumeRole }}" 58 | } 59 | ], 60 | "Tags": [ 61 | { 62 | "Key": "AWSSupport-AutomationExecution", 63 | "Value": "{{ automation:EXECUTION_ID }}" 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "name": "configureIAM", 70 | "action": "aws:invokeLambdaFunction", 71 | "onFailure": "step:deleteDocumentStack", 72 | "inputs": { 73 | "FunctionName": "AWSSupport-ConfigureIAM-{{ automation:EXECUTION_ID }}", 74 | "Payload": "{\"ResourceProperties\": {\"IAMGroupName\": \"{{ IAMGroupName }}\", \"Permissions\": \"{{ Permissions }}\", \"IAMUserName\": \"{{ IAMUserName }}\", \"Region\": \"{{ global:REGION }}\", \"AccountId\": \"{{ global:ACCOUNT_ID }}\", \"ExecutionId\": \"{{ automation:EXECUTION_ID }}\" }}" 75 | } 76 | }, 77 | { 78 | "name": "deleteDocumentStack", 79 | "action": "aws:deleteStack", 80 | "inputs": { 81 | "StackName": "AWSSupport-GrantPermissionsToIAMUser-{{ automation:EXECUTION_ID }}" 82 | } 83 | } 84 | ], 85 | "outputs": [ 86 | "configureIAM.Payload" 87 | ] 88 | } 89 | -------------------------------------------------------------------------------- /documents/AWSSupport-RunEC2RescueForWindowsTool: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Runs EC2Rescue for Windows on the Windows instance to perform the specified action.", 4 | "parameters": { 5 | "Command": { 6 | "type": "String", 7 | "description": "(Required) Choose one of: ResetAccess - Resets the local Administrator password and stores the new password in Parameter Store | CollectLogs: Collects troubleshooting logs from the Operating System, and uploads them to an S3 bucket in your account | FixAll: Attempts to fix an offline Windows root volume attached to the current instance", 8 | "default": "ResetAccess", 9 | "allowedValues": [ 10 | "ResetAccess", 11 | "CollectLogs", 12 | "FixAll" 13 | ] 14 | }, 15 | "Parameters": { 16 | "type": "String", 17 | "description": "(Required) Parameters for the command: ResetAccess - KMS Key ID to encrypt the new Administrator password | CollectLogs: S3 bucket to upload the logs to | FixAll: Device name for the offline remediation.", 18 | "default": "alias/aws/ssm" 19 | } 20 | }, 21 | "mainSteps": [ 22 | { 23 | "precondition": { 24 | "StringEquals": [ 25 | "platformType", 26 | "Windows" 27 | ] 28 | }, 29 | "action": "aws:configurePackage", 30 | "maxAttempts": 3, 31 | "name": "installEC2Rescue", 32 | "inputs": { 33 | "name": "AWSSupport-EC2Rescue", 34 | "action": "Install", 35 | "version": "latest" 36 | } 37 | }, 38 | { 39 | "precondition": { 40 | "StringEquals": [ 41 | "platformType", 42 | "Windows" 43 | ] 44 | }, 45 | "action": "aws:runPowerShellScript", 46 | "name": "runEC2RescueForWindows", 47 | "inputs": { 48 | "runCommand": [ 49 | "if(Get-Module -ListAvailable -Name AWSPowershell){ ", 50 | " Import-Module AWSPowershell, EC2Rescue ", 51 | " $command = \"{{ Command }}\" ", 52 | " $parameters = \"{{ Parameters }}\" ", 53 | " $parameters = $parameters.Trim() ", 54 | " if([string]::IsNullOrWhiteSpace($parameters)){ ", 55 | " Write-Host \"No parameters specified.\" ", 56 | " Exit 255 ", 57 | " } ", 58 | " switch ($command) { ", 59 | " FixAll { ", 60 | " $output = Invoke-EC2RescueFixAll -BlockDeviceName $parameters ", 61 | " if(!$output){ ", 62 | " Write-Host \"Failed to rescue offline volume ${parameters}\" ", 63 | " Exit 255 ", 64 | " }else{ ", 65 | " Write-Host $output ", 66 | " } ", 67 | " } ", 68 | " CollectLogs { ", 69 | " $s3BucketName = $parameters ", 70 | " $s3Path = \"AWSSupport-RunEC2RescueForWindowsTool/\" ", 71 | " if(Test-S3Bucket -BucketName $s3BucketName){ ", 72 | " Write-Host \"Collecting logs from the current Windows instance.\" ", 73 | " $logFile = Invoke-EC2RescueCollectLogBundle -Logs \"all\" ", 74 | " Write-Host \"Log collection completed. Uploading logs to S3 bucket ${s3BucketName} under path ${s3Path}.\" ", 75 | " Copy-EC2RescueLogBundleToS3 -FilePath $logFile -S3BucketName $s3BucketName -S3Path $s3Path ", 76 | " Write-Host \"Log upload completed.\" ", 77 | " }else{ ", 78 | " Write-Host (\"No S3 bucket called \" + $s3BucketName + \" found in the current AWS account, or access denied. Please specify an S3 bucket you own, and that this instance has access to.\") ", 79 | " Exit 255 ", 80 | " } ", 81 | " } ", 82 | " ResetAccess { ", 83 | " Invoke-EC2RescueResetPasswordWithParameterStore -KMSKey $parameters ", 84 | " } ", 85 | " } ", 86 | "}else{ ", 87 | " Write-Host 'AWS Tools for Windows PowerShell not installed. Please install the latest version of the AWS Tools for Windows PowerShell and try again.' ", 88 | " Write-Host 'Download location: https://aws.amazon.com/powershell/' ", 89 | " Exit 255 ", 90 | "}" 91 | ] 92 | } 93 | } 94 | ] 95 | } 96 | -------------------------------------------------------------------------------- /documents/AWSSupport-TerminateIPMonitoringFromVPC: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "AWSSupport-TerminateIPMonitoringFromVPC terminates an IP monitoring test previously started by AWSSupport-SetupIPMonitoringFromVPC. Data related to the specified test ID will be deleted.", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "AutomationExecutionId": { 7 | "type": "String", 8 | "description": "(Required) AWSSupport-SetupIPMonitoringFromVPC automation execution ID of the test you want to terminate." 9 | }, 10 | "SubnetId": { 11 | "type": "String", 12 | "description": "(Required) The subnet ID for the monitor instance.", 13 | "allowedPattern": "^subnet-[a-z0-9]{8,17}$" 14 | }, 15 | "InstanceId": { 16 | "type": "String", 17 | "description": "(Required) The instance ID for the monitor instance.", 18 | "allowedPattern": "^i-[a-z0-9]{8,17}$" 19 | }, 20 | "AutomationAssumeRole": { 21 | "type": "String", 22 | "description": "(Optional) The IAM role for this execution. If no role is specified, AWS Systems Manager Automation will use the permissions of the user that executes this document.", 23 | "default": "" 24 | } 25 | }, 26 | "mainSteps": [ 27 | { 28 | "name": "assertInstanceIdIsAssociatedToTest", 29 | "action": "aws:assertAwsResourceProperty", 30 | "onFailure": "Abort", 31 | "inputs": { 32 | "Service": "ec2", 33 | "Api": "DescribeTags", 34 | "Filters": [ 35 | { 36 | "Name": "tag:AutomationExecutionId", 37 | "Values": [ 38 | "{{ AutomationExecutionId }}" 39 | ] 40 | } 41 | ], 42 | "PropertySelector": "$.Tags[0].ResourceId", 43 | "DesiredValues": [ 44 | "{{ InstanceId }}" 45 | ] 46 | }, 47 | "isCritical": "true", 48 | "nextStep": "assertSubnetIdIsAssociatedToTest" 49 | }, 50 | { 51 | "name": "assertSubnetIdIsAssociatedToTest", 52 | "action": "aws:assertAwsResourceProperty", 53 | "onFailure": "Abort", 54 | "inputs": { 55 | "Service": "ec2", 56 | "Api": "DescribeInstances", 57 | "InstanceIds": [ 58 | "{{ InstanceId }}" 59 | ], 60 | "PropertySelector": "$.Reservations[0].Instances[0].SubnetId", 61 | "DesiredValues": [ 62 | "{{ SubnetId }}" 63 | ] 64 | }, 65 | "isCritical": "true", 66 | "nextStep": "describeTestSecurityGroup" 67 | }, 68 | { 69 | "name": "describeTestSecurityGroup", 70 | "action": "aws:executeAwsApi", 71 | "onFailure": "Continue", 72 | "inputs": { 73 | "Service": "ec2", 74 | "Api": "DescribeSecurityGroups", 75 | "Filters": [ 76 | { 77 | "Name": "group-name", 78 | "Values": [ 79 | "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}" 80 | ] 81 | } 82 | ] 83 | }, 84 | "outputs": [ 85 | { 86 | "Name": "GroupId", 87 | "Selector": "$.SecurityGroups[0].GroupId" 88 | } 89 | ], 90 | "isCritical": "true", 91 | "nextStep": "deleteDashboard" 92 | }, 93 | { 94 | "name": "deleteDashboard", 95 | "action": "aws:executeAwsApi", 96 | "onFailure": "Continue", 97 | "inputs": { 98 | "Service": "cloudwatch", 99 | "Api": "DeleteDashboards", 100 | "DashboardNames": [ 101 | "{{ SubnetId }}_{{ InstanceId }}" 102 | ] 103 | }, 104 | "isCritical": "true", 105 | "nextStep": "terminateInstance" 106 | }, 107 | { 108 | "name": "terminateInstance", 109 | "action": "aws:changeInstanceState", 110 | "onFailure": "Continue", 111 | "inputs": { 112 | "InstanceIds": [ 113 | "{{ InstanceId }}" 114 | ], 115 | "CheckStateOnly": false, 116 | "DesiredState": "terminated" 117 | }, 118 | "isCritical": "true", 119 | "nextStep": "removeIAMRoleFromInstanceProfile" 120 | }, 121 | { 122 | "name": "removeIAMRoleFromInstanceProfile", 123 | "action": "aws:executeAwsApi", 124 | "onFailure": "Continue", 125 | "inputs": { 126 | "Service": "iam", 127 | "Api": "RemoveRoleFromInstanceProfile", 128 | "RoleName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}", 129 | "InstanceProfileName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}" 130 | }, 131 | "isCritical": "true", 132 | "nextStep": "deleteIAMInstanceProfile" 133 | }, 134 | { 135 | "name": "deleteIAMInstanceProfile", 136 | "action": "aws:executeAwsApi", 137 | "onFailure": "Continue", 138 | "inputs": { 139 | "Service": "iam", 140 | "Api": "DeleteInstanceProfile", 141 | "InstanceProfileName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}" 142 | }, 143 | "isCritical": "true", 144 | "nextStep": "removeCloudWatchInlinePolicyFromEC2Role" 145 | }, 146 | { 147 | "name": "removeCloudWatchInlinePolicyFromEC2Role", 148 | "action": "aws:executeAwsApi", 149 | "onFailure": "Continue", 150 | "inputs": { 151 | "Service": "iam", 152 | "Api": "DeleteRolePolicy", 153 | "RoleName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}", 154 | "PolicyName": "SetupIPMonitoringFromVPC_CWPermissions" 155 | }, 156 | "isCritical": "true", 157 | "nextStep": "detachSSMManagedPolicyFromEC2Role" 158 | }, 159 | { 160 | "name": "detachSSMManagedPolicyFromEC2Role", 161 | "action": "aws:executeAwsApi", 162 | "onFailure": "Continue", 163 | "inputs": { 164 | "Service": "iam", 165 | "Api": "DetachRolePolicy", 166 | "PolicyArn": "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM", 167 | "RoleName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}" 168 | }, 169 | "isCritical": "true", 170 | "nextStep": "deleteEC2Role" 171 | }, 172 | { 173 | "name": "deleteEC2Role", 174 | "action": "aws:executeAwsApi", 175 | "onFailure": "Continue", 176 | "inputs": { 177 | "Service": "iam", 178 | "Api": "DeleteRole", 179 | "RoleName": "SetupIPMonitoringFromVPC_{{ AutomationExecutionId }}" 180 | }, 181 | "isCritical": "true", 182 | "nextStep": "deleteSecurityGroup" 183 | }, 184 | { 185 | "name": "deleteSecurityGroup", 186 | "action": "aws:executeAwsApi", 187 | "onFailure": "Continue", 188 | "inputs": { 189 | "Service": "ec2", 190 | "Api": "DeleteSecurityGroup", 191 | "GroupId": "{{ describeTestSecurityGroup.GroupId }}" 192 | }, 193 | "isCritical": "true", 194 | "isEnd": "true" 195 | } 196 | ] 197 | } 198 | -------------------------------------------------------------------------------- /documents/AWSSupport-TroubleshootSSH: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "0.3", 3 | "description": "The AWSSupport-TroubleshootSSH automation document installs the Amazon EC2Rescue tool for Linux, and then uses the EC2Rescue tool to check or attempt to fix common issues that prevent a remote connection to the Linux machine via SSH. Optionally, changes can be applied offline by stopping and starting the instance, if the user explicitly allows for offline remediation. By default, the document operates in read-only mode.", 4 | "assumeRole": "{{ AutomationAssumeRole }}", 5 | "parameters": { 6 | "InstanceId": { 7 | "type": "String", 8 | "description": "(Required) ID of your EC2 Linux instance.", 9 | "allowedPattern": "^[m]{0,1}i-[a-z0-9]{8,17}$" 10 | }, 11 | "Action": { 12 | "description": "(Required) Specify whether to check for issues without fixing them or to check and automatically fix any discovered issues.", 13 | "type": "String", 14 | "allowedValues": [ 15 | "CheckAll", 16 | "FixAll" 17 | ], 18 | "default": "CheckAll" 19 | }, 20 | "AllowOffline": { 21 | "type": "String", 22 | "description": "(Optional) Fix only - Set it to true if you allow an offline SSH remediation in case the online troubleshooting fails, or the provided instance is not a managed instance. Note: For the offline remediation, SSM Automation stops the instance, and creates an AMI before attempting any operations.", 23 | "default": "False", 24 | "allowedValues": [ 25 | "True", 26 | "False" 27 | ] 28 | }, 29 | "SubnetId": { 30 | "type": "String", 31 | "description": "(Optional) Offline only - The subnet ID for the EC2Rescue instance used to perform the offline troubleshooting. If no subnet ID is specified, AWS Systems Manager Automation will create a new VPC. IMPORTANT: The subnet must be in the same Availability Zone as InstanceId, and it must allow access to the SSM endpoints.", 32 | "default": "SelectedInstanceSubnet", 33 | "allowedPattern": "^$|^subnet-[a-z0-9]{8,17}$|SelectedInstanceSubnet" 34 | }, 35 | "S3BucketName": { 36 | "description": "(Optional) Offline only - S3 bucket name in your account where you want to upload the troubleshooting logs. Make sure the bucket policy does not grant unnecessary read/write permissions to parties that do not need access to the collected logs.", 37 | "allowedPattern": "^$|^[_a-zA-Z0-9][-._a-zA-Z0-9]{2,62}$", 38 | "type": "String", 39 | "default": "" 40 | }, 41 | "AutomationAssumeRole": { 42 | "type": "String", 43 | "description": "(Optional) The IAM role for this execution. If no role is specified, AWS Systems Manager Automation will use the permissions of the user that executes this document.", 44 | "default": "" 45 | } 46 | }, 47 | "mainSteps": [ 48 | { 49 | "name": "assertInstanceIsManagedInstance", 50 | "action": "aws:assertAwsResourceProperty", 51 | "onFailure": "step:assertAllowOffline", 52 | "inputs": { 53 | "Service": "ssm", 54 | "Api": "DescribeInstanceInformation", 55 | "InstanceInformationFilterList": [ 56 | { 57 | "key": "InstanceIds", 58 | "valueSet": [ 59 | "{{ InstanceId }}" 60 | ] 61 | } 62 | ], 63 | "PropertySelector": "$.InstanceInformationList[0].PingStatus", 64 | "DesiredValues": [ 65 | "Online" 66 | ] 67 | }, 68 | "isCritical": "false", 69 | "nextStep": "installEC2Rescue" 70 | }, 71 | { 72 | "name": "installEC2Rescue", 73 | "action": "aws:runCommand", 74 | "onFailure": "Abort", 75 | "inputs": { 76 | "DocumentName": "AWS-ConfigureAWSPackage", 77 | "InstanceIds": [ 78 | "{{ InstanceId }}" 79 | ], 80 | "Parameters": { 81 | "name": "AWSSupport-EC2Rescue", 82 | "action": "Install", 83 | "version": "latest" 84 | } 85 | }, 86 | "nextStep": "troubleshootSSH" 87 | }, 88 | { 89 | "name": "troubleshootSSH", 90 | "action": "aws:runCommand", 91 | "onFailure": "Abort", 92 | "inputs": { 93 | "DocumentName": "AWS-RunShellScript", 94 | "InstanceIds": [ 95 | "{{ InstanceId }}" 96 | ], 97 | "Parameters": { 98 | "commands": [ 99 | "#!/bin/sh ", 100 | "error_trap() ", 101 | "{ ", 102 | " printf \"%.s=\" $(seq 1 80) ", 103 | " printf \"The EC2Rescue execution did not complete successfully.\\\\n\" ", 104 | " exit 1 ", 105 | "} ", 106 | " ", 107 | "REMEDIATE=\"\" ", 108 | " ", 109 | "if test {{ Action }} = \"FixAll\" ; then ", 110 | " REMEDIATE=\"--remediate\" ", 111 | "fi ", 112 | " ", 113 | "printf \"Running EC2 Rescue for Linux\\\\n\" ", 114 | "sudo ec2rl run ${REMEDIATE} --only-modules=openssh || error_trap " 115 | ] 116 | } 117 | }, 118 | "isEnd": "true" 119 | }, 120 | { 121 | "name": "assertAllowOffline", 122 | "action": "aws:assertAwsResourceProperty", 123 | "onFailure": "Abort", 124 | "inputs": { 125 | "Service": "ssm", 126 | "Api": "GetAutomationExecution", 127 | "AutomationExecutionId": "{{ automation:EXECUTION_ID }}", 128 | "PropertySelector": "$.AutomationExecution.Parameters.AllowOffline[0]", 129 | "DesiredValues": [ 130 | "True" 131 | ] 132 | }, 133 | "nextStep": "assertActionIsFixAll" 134 | }, 135 | { 136 | "name": "assertActionIsFixAll", 137 | "action": "aws:assertAwsResourceProperty", 138 | "onFailure": "Abort", 139 | "inputs": { 140 | "Service": "ssm", 141 | "Api": "GetAutomationExecution", 142 | "AutomationExecutionId": "{{ automation:EXECUTION_ID }}", 143 | "PropertySelector": "$.AutomationExecution.Parameters.Action[0]", 144 | "DesiredValues": [ 145 | "FixAll" 146 | ] 147 | }, 148 | "nextStep": "assertSubnetId" 149 | }, 150 | { 151 | "name": "assertSubnetId", 152 | "action": "aws:assertAwsResourceProperty", 153 | "onFailure": "step:troubleshootSSHOffline", 154 | "inputs": { 155 | "Service": "ssm", 156 | "Api": "GetAutomationExecution", 157 | "AutomationExecutionId": "{{ automation:EXECUTION_ID }}", 158 | "PropertySelector": "$.AutomationExecution.Parameters.SubnetId[0]", 159 | "DesiredValues": [ 160 | "SelectedInstanceSubnet" 161 | ] 162 | }, 163 | "isCritical": "false", 164 | "nextStep": "describeSourceInstance" 165 | }, 166 | { 167 | "name": "describeSourceInstance", 168 | "action": "aws:executeAwsApi", 169 | "onFailure": "Abort", 170 | "inputs": { 171 | "Service": "ec2", 172 | "Api": "DescribeInstances", 173 | "InstanceIds": [ 174 | "{{ InstanceId }}" 175 | ] 176 | }, 177 | "outputs": [ 178 | { 179 | "Name": "SubnetId", 180 | "Selector": "$.Reservations[0].Instances[0].NetworkInterfaces[0].SubnetId", 181 | "Type": "String" 182 | } 183 | ], 184 | "nextStep": "troubleshootSSHOfflineWithSubnetId" 185 | }, 186 | { 187 | "name": "troubleshootSSHOffline", 188 | "action": "aws:executeAutomation", 189 | "onFailure": "Abort", 190 | "inputs": { 191 | "RuntimeParameters": { 192 | "UnreachableInstanceId": [ 193 | "{{ InstanceId }}" 194 | ], 195 | "SubnetId": [ 196 | "{{ SubnetId }}" 197 | ], 198 | "LogDestination": [ 199 | "{{ S3BucketName }}" 200 | ], 201 | "AssumeRole": [ 202 | "{{ AutomationAssumeRole }}" 203 | ] 204 | }, 205 | "DocumentName": "AWSSupport-ExecuteEC2Rescue" 206 | }, 207 | "isEnd": "true" 208 | }, 209 | { 210 | "name": "troubleshootSSHOfflineWithSubnetId", 211 | "action": "aws:executeAutomation", 212 | "onFailure": "Abort", 213 | "inputs": { 214 | "RuntimeParameters": { 215 | "UnreachableInstanceId": [ 216 | "{{ InstanceId }}" 217 | ], 218 | "SubnetId": [ 219 | "{{ describeSourceInstance.SubnetId }}" 220 | ], 221 | "LogDestination": [ 222 | "{{ S3BucketName }}" 223 | ], 224 | "AssumeRole": [ 225 | "{{ AutomationAssumeRole }}" 226 | ] 227 | }, 228 | "DocumentName": "AWSSupport-ExecuteEC2Rescue" 229 | }, 230 | "isEnd": "true" 231 | } 232 | ], 233 | "outputs": [ 234 | "troubleshootSSH.Output", 235 | "troubleshootSSHOffline.Output", 236 | "troubleshootSSHOfflineWithSubnetId.Output" 237 | ] 238 | } 239 | -------------------------------------------------------------------------------- /documents/AmazonCloudWatch-ManageAgent: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Send commands to Amazon CloudWatch Agent", 4 | "parameters": { 5 | "action": { 6 | "description": "The action CloudWatch Agent should take.", 7 | "type": "String", 8 | "default": "configure", 9 | "allowedValues": [ 10 | "configure", 11 | "configure (append)", 12 | "start", 13 | "status", 14 | "stop" 15 | ] 16 | }, 17 | "mode": { 18 | "description": "Controls platform-specific default behavior such as whether to include EC2 Metadata in metrics.", 19 | "type": "String", 20 | "default": "ec2", 21 | "allowedValues": [ 22 | "ec2", 23 | "onPremise", 24 | "auto" 25 | ] 26 | }, 27 | "optionalConfigurationSource": { 28 | "description": "Only for 'configure' action. Store of the configuration. For CloudWatch Agent's defaults, use 'default'", 29 | "type": "String", 30 | "allowedValues": [ 31 | "default", 32 | "ssm" 33 | ], 34 | "default": "ssm" 35 | }, 36 | "optionalConfigurationLocation": { 37 | "description": "Only for 'configure' actions. Required if loading CloudWatch Agent config from other locations except 'default'. The value is like ssm parameter store name for ssm config source.", 38 | "type": "String", 39 | "default": "", 40 | "allowedPattern": "[^\"]*" 41 | }, 42 | "optionalRestart": { 43 | "description": "Only for 'configure' actions. If 'yes', restarts the agent to use the new configuration. Otherwise the new config will only apply on the next agent restart.", 44 | "type": "String", 45 | "default": "yes", 46 | "allowedValues": [ 47 | "yes", 48 | "no" 49 | ] 50 | } 51 | }, 52 | "mainSteps": [ 53 | { 54 | "name": "ControlCloudWatchAgentWindows", 55 | "action": "aws:runPowerShellScript", 56 | "precondition": { 57 | "StringEquals": [ 58 | "platformType", 59 | "Windows" 60 | ] 61 | }, 62 | "inputs": { 63 | "runCommand": [ 64 | " Set-StrictMode -Version 2.0", 65 | " $ErrorActionPreference = 'Stop'", 66 | " $Cmd = \"${Env:ProgramFiles}\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent-ctl.ps1\"", 67 | " if (!(Test-Path -LiteralPath \"${Cmd}\")) {", 68 | " Write-Output 'CloudWatch Agent not installed. Please install it using the AWS-ConfigureAWSPackage SSM Document.'", 69 | " exit 1", 70 | " }", 71 | " $Params = @()", 72 | " $Action = '{{action}}'", 73 | " if ($Action -eq 'configure') {", 74 | " $Action = 'fetch-config'", 75 | " } elseif ($Action -eq 'configure (append)') {", 76 | " $Action = 'append-config'", 77 | " }", 78 | " if ($Action -eq 'fetch-config' -Or $Action -eq 'append-config') {", 79 | " $Config = '{{optionalConfigurationLocation}}'", 80 | " if ('{{optionalConfigurationSource}}' -eq 'ssm') {", 81 | " if (!(\"${Config}\")) {", 82 | " Write-Output 'SSM Parameter Store name is required when configuring from Parameter Store.'", 83 | " exit 1", 84 | " } else {", 85 | " $Config = \"ssm:${Config}\"", 86 | " }", 87 | " } else {", 88 | " $Config = 'default'", 89 | " }", 90 | " $Params += ('-c', \"${Config}\")", 91 | " if ('{{optionalRestart}}' -eq 'yes') {", 92 | " $Params += '-s'", 93 | " }", 94 | " }", 95 | " $Params += ('-a', \"${Action}\", '-m', '{{mode}}')", 96 | " Invoke-Expression \"& '${Cmd}' ${Params}\"", 97 | " Set-StrictMode -Off", 98 | " exit $LASTEXITCODE" 99 | ] 100 | } 101 | }, 102 | { 103 | "name": "ControlCloudWatchAgentLinux", 104 | "action": "aws:runShellScript", 105 | "precondition": { 106 | "StringEquals": [ 107 | "platformType", 108 | "Linux" 109 | ] 110 | }, 111 | "inputs": { 112 | "runCommand": [ 113 | " #!/bin/sh", 114 | " set -e", 115 | " set -u", 116 | " cmd='/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl'", 117 | " if [ ! -x \"${cmd}\" ]; then", 118 | " echo 'CloudWatch Agent not installed. Please install it using the AWS-ConfigureAWSPackage SSM Document.'", 119 | " exit 1", 120 | " fi", 121 | " action=\"{{action}}\"", 122 | " if [ \"${action}\" = 'configure' ]; then", 123 | " action='fetch-config'", 124 | " elif [ \"${action}\" = 'configure (append)' ]; then", 125 | " action='append-config'", 126 | " fi", 127 | " if [ \"${action}\" = 'fetch-config' ] || [ \"${action}\" = 'append-config' ]; then", 128 | " config='{{optionalConfigurationLocation}}'", 129 | " if [ '{{optionalConfigurationSource}}' = 'ssm' ]; then", 130 | " if [ ! \"${config}\" ]; then", 131 | " echo 'SSM Parameter Store name is required when configuring from Parameter Store.'", 132 | " exit 1", 133 | " else", 134 | " config=\"ssm:${config}\"", 135 | " fi", 136 | " else", 137 | " config='default'", 138 | " fi", 139 | " cmd=\"${cmd} -c ${config}\"", 140 | " if [ '{{optionalRestart}}' = 'yes' ]; then", 141 | " cmd=\"${cmd} -s\"", 142 | " fi", 143 | " fi", 144 | " cmd=\"${cmd} -a ${action} -m {{mode}}\"", 145 | " ${cmd}" 146 | ] 147 | } 148 | } 149 | ] 150 | } 151 | -------------------------------------------------------------------------------- /documents/AmazonCloudWatch-MigrateCloudWatchAgent: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "2.2", 3 | "description": "Assists in migrating from the SSM CloudWatch Plugin to the Amazon CloudWatch Agent", 4 | "mainSteps": [ 5 | { 6 | "name": "checkSsmAgentVersion", 7 | "action": "aws:runPowerShellScript", 8 | "precondition": { 9 | "StringEquals": [ 10 | "platformType", 11 | "Windows" 12 | ] 13 | }, 14 | "inputs": { 15 | "runCommand": [ 16 | "$ssmAgentVersion = (Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | select DisplayName, DisplayVersion | Where DisplayName -eq 'Amazon SSM Agent').'DisplayVersion'", 17 | "if ([System.Version]$ssmAgentVersion -ge [System.Version]'2.2.93.0') {", 18 | "echo 'You have a valid SSM agent version for migration'", 19 | "} else {", 20 | "Throw 'The current SSM agent version ' + $ssmAgentVersion + ' does not support the new CloudWatch agent. Please consider updating your SSM agent to version 2.2.93.0 or newer.'", 21 | "}" 22 | ] 23 | } 24 | }, 25 | { 26 | "name": "disableOldCloudWatchAgent", 27 | "action": "aws:cloudWatch", 28 | "precondition": { 29 | "StringEquals": [ 30 | "platformType", 31 | "Windows" 32 | ] 33 | }, 34 | "settings": { 35 | "startType": "Disabled" 36 | } 37 | }, 38 | { 39 | "name": "installNewCloudWatchAgent", 40 | "action": "aws:runDocument", 41 | "precondition": { 42 | "StringEquals": [ 43 | "platformType", 44 | "Windows" 45 | ] 46 | }, 47 | "inputs": { 48 | "documentType": "SSMDocument", 49 | "documentPath": "AWS-ConfigureAWSPackage", 50 | "documentParameters": "action: Install\nname: AmazonCloudWatchAgent\nversion: latest" 51 | } 52 | }, 53 | { 54 | "name": "migrateOldConfiguration", 55 | "action": "aws:runPowerShellScript", 56 | "precondition": { 57 | "StringEquals": [ 58 | "platformType", 59 | "Windows" 60 | ] 61 | }, 62 | "inputs": { 63 | "runCommand": [ 64 | "Set-Location -Path \"${Env:ProgramFiles}\\Amazon\\AmazonCloudWatchAgent\" -PassThru", 65 | "if (Test-Path \"${Env:ProgramFiles}\\Amazon\\SSM\\Plugins\\awsCloudWatch\\AWS.EC2.Windows.CloudWatch.json\") {", 66 | "$stdOut = .\\amazon-cloudwatch-agent-config-wizard.exe --isNonInteractiveWindowsMigration 2>($tmpFile = [System.IO.Path]::GetTempFileName())", 67 | "$stdErr = Get-Content $tmpFile; Remove-Item $tmpFile", 68 | "if ( $LastExitCode -ne 0 ) {", 69 | "Throw 'Failed to migrate the old config. Please check that you have a valid SSM agent version and a valid old agent Config file. \\n stdout = ' + $stdOut + ', stderr = ' + $stdErr", 70 | "}", 71 | "} else {", 72 | "Throw 'No SSM CloudWatch Plugin configuration file found. Please, follow the Amazon CloudWatch Agent configuration instructions instead.'", 73 | "}" 74 | ] 75 | } 76 | }, 77 | { 78 | "name": "reconfigureNewAgent", 79 | "action": "aws:runPowerShellScript", 80 | "precondition": { 81 | "StringEquals": [ 82 | "platformType", 83 | "Windows" 84 | ] 85 | }, 86 | "inputs": { 87 | "runCommand": [ 88 | "Set-Location -Path \"${Env:ProgramFiles}\\Amazon\\AmazonCloudWatchAgent\" -PassThru", 89 | ".\\amazon-cloudwatch-agent-ctl.ps1 -a fetch-config -m ec2 -c file:config.json -s" 90 | ] 91 | } 92 | } 93 | ] 94 | } 95 | --------------------------------------------------------------------------------