├── .gitignore ├── AmazonObservability ├── .gitignore ├── AmazonCloudWatchLogs │ ├── LogInsightsUsage │ │ ├── .gitignore │ │ ├── scripts │ │ │ └── get-log-insights-query-info │ │ │ │ ├── get-log-insights-query-info.sh │ │ │ │ └── README.md │ │ └── templates │ │ │ └── CWLogInsightsUsageDashboard │ │ │ └── README.md │ └── .DS_Store ├── .DS_Store ├── AmazonQOperations │ ├── .DS_Store │ ├── SampleApp │ │ ├── .DS_Store │ │ └── template │ │ │ └── AmazonQOperationSampleApp.yml │ ├── scripts │ │ └── LoadGen.py │ └── Canary │ │ └── SyntheticsCanary.yml └── AmazonCloudWatchMetrics │ ├── .DS_Store │ └── CustomWidgets │ └── MetricsUsage │ └── GetData.py ├── AWSConfig ├── AWS-Config-OPA │ ├── lambda_sources │ │ ├── layers │ │ │ └── opa │ │ │ │ └── bin │ │ │ │ └── .gitignore │ │ ├── function │ │ │ ├── lambda_requirements.txt │ │ │ ├── .gitignore │ │ │ └── opa_lambda.py │ │ └── packaged_lambda_assets │ │ │ └── ,gitignore │ ├── opa_policies │ │ ├── opa_policy_ebs_encryption.rego │ │ ├── opa_policy_eip_attachment.rego │ │ ├── opa_policy_ebs_attachment.rego │ │ └── opa_policy_s3_encryption.rego │ ├── package_lambda.sh │ ├── cfn_templates │ │ ├── config_rules │ │ │ ├── opa-ebs-encryption.yaml │ │ │ ├── opa-eip-attachment.yaml │ │ │ ├── opa-ebs-attachment.yaml │ │ │ └── opa-s3-encryption.yaml │ │ └── lambda_backend │ │ │ └── opa-lambda.yaml │ └── README.md ├── CloudEndureCheckReplication │ ├── overview.png │ └── README.md ├── README.md ├── ConformancePacks │ ├── CP-Prerequisites.yaml │ └── CP-IAMBestPractices.yaml └── AWS-Config-Visualization │ └── README.md ├── AWSCloudTrail ├── cloudtraillake-orchestrator │ ├── .npmignore │ ├── .gitignore │ ├── cloudformation-launch-stack.png │ ├── jest.config.js │ ├── bin │ │ └── cloudtraillake-orchestrator.ts │ ├── config.ts │ ├── test │ │ └── cloudtraillake-orchestrator.test.ts │ ├── package.json │ ├── tsconfig.json │ ├── cdk_synth_simple.sh │ ├── cdk.json │ ├── step-functions │ │ └── state-machine.json │ ├── lambda │ │ └── cloudtraillake-query.py │ ├── archive │ │ └── step-function-s3-audit.json │ ├── README.md │ └── lib │ │ └── cloudtraillake-orchestrator-stack.ts ├── cloudtrail-lake-analysis │ ├── images │ │ ├── widget-config.png │ │ └── widget_selection_staging.jpg │ └── README.md └── EnableAWSCloudtrail-ExcludeKMS.yml ├── ~$kiaiops.docx ├── AWSSystemsManager ├── AWS-Org-SSM-Permissions │ ├── docs │ │ └── diagram.png │ ├── ssm-management-account │ │ ├── getaccountid │ │ │ ├── package.json │ │ │ └── index.js │ │ ├── invitationtest │ │ │ ├── package.json │ │ │ └── index.js │ │ ├── publishaccountid │ │ │ ├── package.json │ │ │ └── index.js │ │ ├── .gitignore │ │ └── README.md │ ├── ssm-child-account │ │ ├── README.md │ │ └── template.yaml │ └── README.md ├── CentralizedPatchManagement │ ├── images │ │ ├── opsmgmt-diagram.png │ │ ├── opsmgmt-orgtree.png │ │ ├── opsmgmt-example-central-cfn-picture.png │ │ ├── opsmgmt-example-target-cfn-picture.png │ │ ├── opsmgmt-example-target-deployment-cfn-picture.png │ │ └── opsmgmt-example-operations-central-cfn-picture.png │ ├── opsmgmt-target-account.yaml │ └── opsmgmt-deploy-test-instances.yaml ├── Quick-Setup-API │ ├── host-management-examples │ │ ├── host-mgmt-cli-input.yaml │ │ ├── host-mgmt-cli-input.json │ │ └── host-mgmt-cfn-template.yaml │ ├── dhmc-examples │ │ ├── dhmc-cli-input.yaml │ │ ├── dhmc-cli-input.json │ │ └── dhmc-cfn-template.yaml │ └── patch-policy-examples │ │ ├── default-patch-baselines.txt │ │ ├── patch-policy-cli-input.yaml │ │ ├── patch-policy-cli-input.json │ │ └── patch-policy-cfn-template.yaml └── ConfigurationManagement │ ├── README.md │ ├── exampleCommandDocument.yml │ └── configurationManagementExampleLambda.py ├── CODE_OF_CONDUCT.md ├── .vscode ├── launch.json └── settings.json ├── README.md ├── AWSServiceCatalog ├── README.md └── cdk_sc_sample │ ├── README.md │ └── cdk_sc_sample_stack.py ├── LICENSE ├── AWSAuditManager └── auditmanager-config-evidence-collection │ └── README.md ├── CONTRIBUTING.md └── AWSLicenseManager └── TrackLicenses_MultiRegion └── LM-MULTIREGION_LicenseTracking.yml /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/.vscode 3 | 4 | -------------------------------------------------------------------------------- /AmazonObservability/.gitignore: -------------------------------------------------------------------------------- 1 | !.DS_store 2 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/lambda_sources/layers/opa/bin/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/lambda_sources/function/lambda_requirements.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/lambda_sources/packaged_lambda_assets/,gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/lambda_sources/function/.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude libraries 2 | lib/ -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchLogs/LogInsightsUsage/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /AmazonObservability/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AmazonObservability/.DS_Store -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | -------------------------------------------------------------------------------- /~$kiaiops.docx: -------------------------------------------------------------------------------- 1 | Andres Silva Andres Silva -------------------------------------------------------------------------------- /AmazonObservability/AmazonQOperations/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AmazonObservability/AmazonQOperations/.DS_Store -------------------------------------------------------------------------------- /AWSConfig/CloudEndureCheckReplication/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSConfig/CloudEndureCheckReplication/overview.png -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchLogs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AmazonObservability/AmazonCloudWatchLogs/.DS_Store -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchMetrics/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AmazonObservability/AmazonCloudWatchMetrics/.DS_Store -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/docs/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/AWS-Org-SSM-Permissions/docs/diagram.png -------------------------------------------------------------------------------- /AmazonObservability/AmazonQOperations/SampleApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AmazonObservability/AmazonQOperations/SampleApp/.DS_Store -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtrail-lake-analysis/images/widget-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSCloudTrail/cloudtrail-lake-analysis/images/widget-config.png -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-diagram.png -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-orgtree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-orgtree.png -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtrail-lake-analysis/images/widget_selection_staging.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSCloudTrail/cloudtrail-lake-analysis/images/widget_selection_staging.jpg -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/cloudformation-launch-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSCloudTrail/cloudtraillake-orchestrator/cloudformation-launch-stack.png -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/opa_policies/opa_policy_ebs_encryption.rego: -------------------------------------------------------------------------------- 1 | package ebs_encryption 2 | 3 | default compliant = false 4 | 5 | compliant = true { 6 | input.resourceType == "AWS::EC2::Volume" 7 | input.configuration.encrypted == true 8 | } -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/opa_policies/opa_policy_eip_attachment.rego: -------------------------------------------------------------------------------- 1 | package eip_attachment 2 | 3 | default compliant = false 4 | 5 | compliant = true { 6 | input.resourceType == "AWS::EC2::EIP" 7 | input.configuration.associationId != null 8 | } -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/opa_policies/opa_policy_ebs_attachment.rego: -------------------------------------------------------------------------------- 1 | package ebs_attachment 2 | 3 | default compliant = false 4 | 5 | compliant = true { 6 | input.resourceType == "AWS::EC2::Volume" 7 | count(input.configuration.attachments) > 0 8 | } -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-central-cfn-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-central-cfn-picture.png -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-target-cfn-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-target-cfn-picture.png -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-target-deployment-cfn-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-target-deployment-cfn-picture.png -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-operations-central-cfn-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-management-and-governance-samples/HEAD/AWSSystemsManager/CentralizedPatchManagement/images/opsmgmt-example-operations-central-cfn-picture.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/bin/cloudtraillake-orchestrator.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from 'aws-cdk-lib'; 3 | import { CloudtraillakeOrchestratorStack } from '../lib/cloudtraillake-orchestrator-stack'; 4 | 5 | const app = new cdk.App(); 6 | new CloudtraillakeOrchestratorStack(app, 'CloudtraillakeOrchestratorStack'); 7 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/getaccountid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambdaefs_efs", 3 | "version": "1.0.0", 4 | "description": "lambdaefs efs function", 5 | "main": "index.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT" 9 | } 10 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/invitationtest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambdaefs_efs", 3 | "version": "1.0.0", 4 | "description": "lambdaefs efs function", 5 | "main": "index.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT" 9 | } 10 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/publishaccountid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambdaefs_efs", 3 | "version": "1.0.0", 4 | "description": "lambdaefs efs function", 5 | "main": "index.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT" 9 | } 10 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/package_lambda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./lambda_sources/function/lib 4 | pip3 install -r ./lambda_sources/function/lambda_requirements.txt -t ./lambda_sources/function/lib/ 5 | cp ./lambda_sources/function/*.py ./lambda_sources/function/lambda_requirements.txt ./lambda_sources/function/lib/ && 6 | cd ./lambda_sources/function/lib && zip -r ../../packaged_lambda_assets/sources.zip . 7 | cd ../../layers && zip -r ../packaged_lambda_assets/opa.zip . 8 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/host-management-examples/host-mgmt-cli-input.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: qs-host-management 3 | Description: Enable Host Management for the AWS Organization 4 | ConfigurationDefinitions: 5 | - Type: AWSQuickSetupType-SSMHostMgmt 6 | Parameters: 7 | CollectInventory: 'true' 8 | ScanInstances: 'false' 9 | UpdateSsmAgent: 'false' 10 | TargetType: "*" 11 | TargetOrganizationalUnits: ab12-cdefgh34 12 | TargetRegions: us-east-1,us-east-2 13 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/opa_policies/opa_policy_s3_encryption.rego: -------------------------------------------------------------------------------- 1 | package s3_bucket_encryption 2 | 3 | default compliant = false 4 | 5 | compliant = true { 6 | input.resourceType == "AWS::S3::Bucket" 7 | 8 | any([ 9 | input.supplementaryConfiguration.ServerSideEncryptionConfiguration.rules[_].applyServerSideEncryptionByDefault.sseAlgorithm == "AES256", 10 | input.supplementaryConfiguration.ServerSideEncryptionConfiguration.rules[_].applyServerSideEncryptionByDefault.sseAlgorithm == "aws:kms" 11 | ]) 12 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python Debugger: Current File", 9 | "type": "debugpy", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal", 13 | "python": "/opt/homebrew/bin/python3" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "yaml.schemas": { 3 | "https://raw.githubusercontent.com/awslabs/goformation/master/schema/cloudformation.schema.json": [ 4 | "file:///Users/andress/Documents/github/aws-management-and-governance-samples/AmazonObservability/AmazonQOperations/SyntheticsCanary.yml", 5 | "file:///Users/andress/Documents/github/aws-management-and-governance-samples/AmazonObservability/AmazonCloudWatchLogs/LogInsightsUsage/templates/CWLogInsightsUsageDashboard/CWLogInsightsUsageDashboard.yaml" 6 | ] 7 | } 8 | } -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/config.ts: -------------------------------------------------------------------------------- 1 | export const Config = { 2 | // The ARN of the CloudTrail Lake Event Data Store 3 | // Permission will be given to the Lambda function to query this event data store 4 | // must start with arn:aws:cloudtrail: 5 | CloudtraillakeEventDataStoreArn: "", 6 | // The email address which will recieve notifications from SNS for any service limit quota limits that are requested 7 | // Note: you will need to check your inbox after deploying the CDK and confirm the SNS subscription 8 | NotifyEmailAddress: "" 9 | }; -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/invitationtest/index.js: -------------------------------------------------------------------------------- 1 | exports.handler = (event, context, callback) => { 2 | var accountid = ""; 3 | var type = ""; 4 | try { 5 | accountid = event.detail.requestParameters.target.id; 6 | type = event.detail.requestParameters.target.type; 7 | if (type == "ACCOUNT") 8 | { 9 | callback(null, {state:"EXISTING", result:accountid}); 10 | } 11 | } catch (e) { 12 | callback(null, {state:"NEW", result:"NEW"}); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/dhmc-examples/dhmc-cli-input.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: qs-dhmc 3 | Description: Enable Default Host Management configuration for the AWS Organization 4 | ConfigurationDefinitions: 5 | - Type: AWSQuickSetupType-DHMC 6 | Parameters: 7 | UpdateSSMAgent: 'true' 8 | TargetOrganizationalUnits: r-1abc 9 | TargetRegions: eu-north-1, ap-south-1, eu-west-3, us-east-2, eu-west-1, eu-central-1, 10 | sa-east-1, us-east-1, ap-northeast-2, eu-west-2, ap-northeast-1, us-west-2, 11 | us-west-1, ap-southeast-1, ap-southeast-2, ca-central-1 12 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/host-management-examples/host-mgmt-cli-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "qs-host-management", 3 | "Description": "Enable Host Management for the AWS Organization", 4 | "ConfigurationDefinitions": [{ 5 | "Type": "AWSQuickSetupType-SSMHostMgmt", 6 | "Parameters": { 7 | "CollectInventory": "true", 8 | "ScanInstances": "false", 9 | "UpdateSsmAgent": "false", 10 | "TargetType": "*", 11 | "TargetOrganizationalUnits": "ou-ab12-cdefgh34", 12 | "TargetRegions": "us-east-1,us-east-2" 13 | } 14 | }] 15 | } -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/dhmc-examples/dhmc-cli-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "qs-dhmc", 3 | "Description": "Enable Default Host Management configuration for the AWS Organization", 4 | "ConfigurationDefinitions": [{ 5 | "Type": "AWSQuickSetupType-DHMC", 6 | "Parameters": { 7 | "UpdateSSMAgent": "true", 8 | "TargetOrganizationalUnits": "r-1abc", 9 | "TargetRegions": "eu-north-1, ap-south-1, eu-west-3, us-east-2, eu-west-1, eu-central-1, sa-east-1, us-east-1, ap-northeast-2, eu-west-2, ap-northeast-1, us-west-2, us-west-1, ap-southeast-1, ap-southeast-2, ca-central-1" 10 | } 11 | }] 12 | } -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/publishaccountid/index.js: -------------------------------------------------------------------------------- 1 | var AWS = require("aws-sdk"); 2 | var sns = new AWS.SNS(); 3 | 4 | exports.handler = (event, context, callback) => { 5 | 6 | var type = event.type; 7 | var accountid = event.accountid; 8 | 9 | var message = {"type":type,"accountid":accountid}; 10 | 11 | var params = { 12 | Message: JSON.stringify(message), 13 | TopicArn: process.env.SNS_ARN 14 | }; 15 | sns.publish(params, function(err, data) { 16 | if (err) callback(null, err.toString()); // an error occurred 17 | else callback(null, params); // successful response 18 | }); 19 | 20 | }; 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## aws-management-and-governance-samples 2 | 3 | This repository contains a collection of samples for the Management and Governance services which includes: CloudWatch, CloudFormation, Cloudtrail, Config, Systems Manager and more. 4 | 5 | The samples are designed to educate AWS customers on how to implement management and governance services. They are organized by service, although some of the samples maybe be leveraging multiple services. 6 | 7 | 8 | ## Security 9 | 10 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 11 | 12 | ## License 13 | 14 | This library is licensed under the MIT-0 License. See the LICENSE file. 15 | 16 | -------------------------------------------------------------------------------- /AWSSystemsManager/ConfigurationManagement/README.md: -------------------------------------------------------------------------------- 1 | ## Centralizing configuration management using AWS Systems Manager 2 | 3 | This repo hosts CloudFormation templates related to the AWS Management & Governance blog post: 4 | 5 | [Centralizing configuration management using AWS Systems Manager](https://aws.amazon.com/blogs/mt/centralizing-configuration-management-using-aws-systems-manager/) 6 | 7 | For details on how to use the corresponding files, refer to the blog post. 8 | 9 | ## Security 10 | 11 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 12 | 13 | ## License 14 | 15 | This library is licensed under the MIT-0 License. See the LICENSE file. 16 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/test/cloudtraillake-orchestrator.test.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import { Template, Match } from 'aws-cdk-lib/assertions'; 3 | import * as CloudtraillakeOrchestrator from '../lib/cloudtraillake-orchestrator-stack'; 4 | 5 | test('SQS Queue and SNS Topic Created', () => { 6 | const app = new cdk.App(); 7 | // WHEN 8 | const stack = new CloudtraillakeOrchestrator.CloudtraillakeOrchestratorStack(app, 'MyTestStack'); 9 | // THEN 10 | 11 | const template = Template.fromStack(stack); 12 | 13 | //template.hasResourceProperties('AWS::SQS::Queue', { 14 | // VisibilityTimeout: 300 15 | //}); 16 | //template.resourceCountIs('AWS::SNS::Topic', 1); 17 | }); 18 | -------------------------------------------------------------------------------- /AWSServiceCatalog/README.md: -------------------------------------------------------------------------------- 1 | ## AWS Service Catalog 2 | 3 | This repository contains sample code for AWS Service Catalog. AWS Service Catalog lets organizations centrally manage and deploy applications and resources through infrastructure as code (IaC) templates. 4 | 5 | ## References 6 | 7 | The following links will provide additional resources to learn about AWS Service Catalog. 8 | 9 | - [AWS Service Catalog](https://aws.amazon.com/servicecatalog/) 10 | - [AWS Service Catalog Workshop](http://servicecatalog.workshop.aws) 11 | 12 | ## Security 13 | 14 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 15 | 16 | ## License 17 | 18 | This library is licensed under the MIT-0 License. See the LICENSE file. 19 | 20 | -------------------------------------------------------------------------------- /AWSServiceCatalog/cdk_sc_sample/README.md: -------------------------------------------------------------------------------- 1 | ## CDK SC Sample Stack - AWS Service Catalog 2 | 3 | This file contains sample code to create an AWS Service Catalog portfolio with a single Service Catalog product. In this example, the product is a S3 bucket. You can choose to add more products to this portfolio. 4 | 5 | 6 | 7 | To deploy, run these commands 8 | 9 | 10 | ``` 11 | $ mkdir cdk_sc_sample && cd cdk_sc_sample 12 | $ cdk init app --language=python 13 | $ pip install -r requirements.txt 14 | ``` 15 | 16 | Copy this cdk_sc_sample repo into your cdk_sc_sample directory. 17 | 18 | After this, you can run the following: 19 | 20 | ``` 21 | $ cdk bootstrap 22 | $ cdk deploy 23 | ``` 24 | 25 | This will deploy the Service Catalog portfolio and its product into your account. -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudtraillake-orchestrator", 3 | "version": "0.1.0", 4 | "bin": { 5 | "cloudtraillake-orchestrator": "bin/cloudtraillake-orchestrator.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "test": "jest", 11 | "cdk": "cdk" 12 | }, 13 | "devDependencies": { 14 | "aws-cdk": "2.28.1", 15 | "@types/jest": "^27.5.2", 16 | "@types/node": "10.17.27", 17 | "@types/prettier": "2.6.0", 18 | "jest": "^27.5.1", 19 | "ts-jest": "^27.1.4", 20 | "ts-node": "^10.8.1", 21 | "typescript": "~3.9.7" 22 | }, 23 | "dependencies": { 24 | "@matthewbonig/state-machine": "^0.0.16", 25 | "aws-cdk-lib": "^2.189.0", 26 | "constructs": "^10.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2018" 7 | ], 8 | "declaration": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": [ 23 | "./node_modules/@types" 24 | ] 25 | }, 26 | "exclude": [ 27 | "node_modules", 28 | "cdk.out" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/getaccountid/index.js: -------------------------------------------------------------------------------- 1 | var AWS = require("aws-sdk"); 2 | var organizations = new AWS.Organizations(); 3 | 4 | exports.handler = (event, context, callback) => { 5 | 6 | var requestid = event.id; 7 | 8 | var params = { 9 | CreateAccountRequestId: requestid 10 | }; 11 | organizations.describeCreateAccountStatus(params, function(err, data) { 12 | if (err) { 13 | console.log(err, err.stack); // an error occurred 14 | } 15 | else 16 | { 17 | var result = data.CreateAccountStatus; 18 | if (result.State == 'SUCCEEDED') 19 | { 20 | callback(null, {state:result.State, result:result.AccountId}); 21 | } 22 | else { 23 | callback(null, {state:result.State,result:"PENDING"}); 24 | } 25 | } 26 | }); 27 | 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonQOperations/scripts/LoadGen.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import time 4 | import random 5 | 6 | API_ENDPOINT = "https://zl75rl3xxb.execute-api.us-east-1.amazonaws.com/prod/users" # Replace with the URL from the stack output 7 | 8 | def send_request(user_id, user_data): 9 | payload = { 10 | 'userId': user_id, 11 | 'userData': user_data 12 | } 13 | response = requests.post(API_ENDPOINT, json=payload) 14 | return response 15 | 16 | # Inject load 17 | for i in range(1000): 18 | user_id = f'user_{i}' 19 | user_data = { 20 | 'name': f'User {i}', 21 | 'age': random.randint(18, 80), 22 | 'email': f'user{i}@example.com' 23 | } 24 | response = send_request(user_id, user_data) 25 | print(f"Request {i}: Status Code {response.status_code}") 26 | time.sleep(0.1) # Small delay to control request rate 27 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchLogs/LogInsightsUsage/scripts/get-log-insights-query-info/get-log-insights-query-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get query IDs and strings 4 | query_info=$(aws logs describe-queries --query 'queries[*].{queryId: queryId, queryString: queryString}' --output json) 5 | 6 | # Check if we got any queries 7 | if [ -z "$query_info" ] || [ "$query_info" == "[]" ]; then 8 | echo "No queries found." 9 | exit 0 10 | fi 11 | 12 | # Iterate through each query 13 | echo "$query_info" | jq -c '.[]' | while read -r query; do 14 | query_id=$(echo $query | jq -r '.queryId') 15 | query_string=$(echo $query | jq -r '.queryString') 16 | 17 | echo "Query ID: $query_id" 18 | echo "Query String: $query_string" 19 | echo "Statistics:" 20 | 21 | # Get statistics for this query 22 | aws logs get-query-results --query-id "$query_id" --query 'statistics' --output yaml 23 | 24 | echo "------------------------" 25 | done 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/cdk_synth_simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # To reduce output of cdk synth, delete below from synth results. 4 | # - delete Parameters.BootstrapVersion 5 | # - delete Rules.CheckBootstrapVersion 6 | # - no-version-reporting 7 | # - path-metadata false 8 | # - asset-metadata false 9 | # 10 | # Usage: 11 | # (Run at cdk root directory) 12 | # bash cdk_synth_simple.sh 13 | # Output: 14 | # tmp.yaml is created and shown. 15 | # 16 | # Note: Used only for one stack cdk. 17 | 18 | # Check if in the cdk root 19 | if [ ! -f cdk.json ]; then 20 | printf "\n--app is required either in command-line, in cdk.json or in ~/.cdk.json.\n" 21 | exit 22 | fi 23 | 24 | FILE="tmp.yaml" 25 | 26 | cdk synth --no-version-reporting --path-metadata false --asset-metadata false | \ 27 | yq 'del( .Parameters.BootstrapVersion )' | \ 28 | yq 'del( .Rules.CheckBootstrapVersion )' | \ 29 | yq 'del(.. | select(tag == "!!map" and length == 0))' > $FILE 30 | 31 | cat $FILE 32 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchMetrics/CustomWidgets/MetricsUsage/GetData.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | from datetime import datetime, timedelta 3 | 4 | def get_total_metrics_count(): 5 | try: 6 | # Create CloudWatch client 7 | cloudwatch = boto3.client('cloudwatch') 8 | 9 | # List all metrics with pagination 10 | paginator = cloudwatch.get_paginator('list_metrics') 11 | 12 | total_metrics = 0 13 | 14 | # Iterate through all pages 15 | for page in paginator.paginate(): 16 | metrics = page['Metrics'] 17 | total_metrics += len(metrics) 18 | 19 | return total_metrics 20 | 21 | except Exception as e: 22 | print(f"Error occurred: {str(e)}") 23 | return None 24 | 25 | def main(): 26 | count = get_total_metrics_count() 27 | if count is not None: 28 | print(f"Total number of metrics: {count}") 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/cloudtraillake-orchestrator.ts", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "**/*.d.ts", 11 | "**/*.js", 12 | "tsconfig.json", 13 | "package*.json", 14 | "yarn.lock", 15 | "node_modules", 16 | "test" 17 | ] 18 | }, 19 | "context": { 20 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 21 | "@aws-cdk/core:stackRelativeExports": true, 22 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 23 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 24 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 25 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 26 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 27 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 28 | "@aws-cdk/core:checkSecretUsage": true, 29 | "@aws-cdk/aws-iam:minimizePolicies": true, 30 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 31 | "@aws-cdk/core:target-partitions": [ 32 | "aws", 33 | "aws-cn" 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /AWSAuditManager/auditmanager-config-evidence-collection/README.md: -------------------------------------------------------------------------------- 1 | # Enhanced Evidence Collection with AWS Config and Audit Manager 2 | 3 | This sample demonstrates how one can leverage custom Config rules to enhance evidence collection in Audit Manager. 4 | Often customers require configuration evidence tied to their Config rule. In this sample, we leverage a custom Config 5 | rule to generate a report with compliant and non-compliant evidence stored in S3. The S3 location is available as an 6 | annotation in the Config rule. When one creates an assessment report in Audit Manager, the annotation is also returned 7 | and one can access the evidence report in S3 at that point. 8 | 9 | ## Pre-requisites 10 | 11 | * AWS Config must be enabled on the region where the rule will be deployed. 12 | * S3 bucket to write evidence reports to. 13 | 14 | ## Deployment Instructions 15 | 16 | Deploy the CloudFormation template in your account. The template requires an existing S3 bucket (name, region and prefix 17 | must be provided) as well as a name for the Config rule and evidence report. 18 | It will create a custom Config rule and Lambda function as well as an IAM role and AWS Systems Manager 19 | Parameter Store parameters which are used by the Lambda function. 20 | 21 | To test this works, go the Config console in the region where the CloudFormation template was deployed 22 | and access the created rule. If no AMIs exist in the region, no evidence will be generated. If AMIs (public or private) 23 | exist, one should see a compliant or non-compliant status and an annotation to the evidence report in S3. -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchLogs/LogInsightsUsage/scripts/get-log-insights-query-info/README.md: -------------------------------------------------------------------------------- 1 | # CloudWatch Logs Query Analyzer 2 | 3 | ## Description 4 | 5 | This Bash script retrieves and analyzes CloudWatch Logs queries using the AWS CLI. It fetches query IDs and strings, then provides detailed statistics for each query. 6 | 7 | ## Prerequisites 8 | 9 | - AWS CLI installed and configured with appropriate permissions 10 | - `jq` command-line JSON processor 11 | - Bash shell 12 | 13 | ## Usage 14 | 15 | 1. Make the script executable: 16 | 17 | `chmod +x get-log-insights-query-info.sh` 18 | 19 | 20 | 2. Run the script: 21 | 22 | `./script_name.sh` 23 | 24 | 25 | ## What the Script Does 26 | 27 | 1. Retrieves query IDs and strings from CloudWatch Logs using `aws logs describe-queries`. 28 | 2. Checks if any queries were found. 29 | 3. For each query: 30 | - Displays the Query ID and Query String. 31 | - Fetches and displays statistics for the query using `aws logs get-query-results`. 32 | 33 | ## Output 34 | 35 | The script outputs: 36 | - Query ID 37 | - Query String 38 | - Query Statistics in YAML format 39 | 40 | If no queries are found, it will display "No queries found." 41 | 42 | ## Error Handling 43 | 44 | The script includes basic error handling: 45 | - Checks if any queries were returned before processing. 46 | - Uses `set -e` to exit on any command errors (optional, not currently in the script). 47 | 48 | ## Dependencies 49 | 50 | - AWS CLI 51 | - jq 52 | 53 | ## Notes 54 | 55 | - Ensure your AWS CLI is configured with the correct permissions to access CloudWatch Logs. 56 | - The script uses the default AWS CLI profile. Modify if you need to use a specific profile. 57 | 58 | 59 | -------------------------------------------------------------------------------- /AWSSystemsManager/ConfigurationManagement/exampleCommandDocument.yml: -------------------------------------------------------------------------------- 1 | --- 2 | schemaVersion: '2.2' 3 | description: Run first a PowerShell script & then the inventory plugin. 4 | mainSteps: 5 | - action: aws:runPowerShellScript 6 | name: runPowerShellScript 7 | inputs: 8 | runCommand: "{{ commands }}" 9 | - action: aws:softwareInventory 10 | name: collectSoftwareInventoryItems 11 | inputs: 12 | applications: "{{ applications }}" 13 | awsComponents: "{{ awsComponents }}" 14 | networkConfig: "{{ networkConfig }}" 15 | windowsUpdates: "{{ windowsUpdates }}" 16 | customInventory: "{{ customInventory }}" 17 | parameters: 18 | commands: 19 | type: StringList 20 | description: "(Required) Specify a shell script or a command to run." 21 | minItems: 1 22 | displayType: textarea 23 | applications: 24 | type: String 25 | default: Enabled 26 | description: "(Optional) Collect data for installed applications." 27 | allowedValues: 28 | - Enabled 29 | - Disabled 30 | awsComponents: 31 | type: String 32 | default: Enabled 33 | description: "(Optional) Collect data for AWSComponents like amazon-ssm-agent." 34 | allowedValues: 35 | - Enabled 36 | - Disabled 37 | networkConfig: 38 | type: String 39 | default: Enabled 40 | description: "(Optional) Collect data for Network configurations." 41 | allowedValues: 42 | - Enabled 43 | - Disabled 44 | windowsUpdates: 45 | type: String 46 | default: Enabled 47 | description: "(Optional) Collect data for all WindowsUpdates." 48 | allowedValues: 49 | - Enabled 50 | - Disabled 51 | customInventory: 52 | type: String 53 | default: Enabled 54 | description: "(Optional) Collect data for custom inventory." 55 | allowedValues: 56 | - Enabled 57 | - Disabled 58 | 59 | -------------------------------------------------------------------------------- /AWSServiceCatalog/cdk_sc_sample/cdk_sc_sample_stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import ( 2 | Stack, 3 | aws_iam as iam, 4 | aws_s3 as s3, 5 | aws_servicecatalog as sc 6 | ) 7 | from constructs import Construct 8 | 9 | class CdkScSampleStack(Stack): 10 | 11 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 12 | super().__init__(scope, construct_id, **kwargs) 13 | 14 | 15 | #Create a Service Catalog portfolio 16 | portfolio = sc.Portfolio(self, 'DevToolsPortfolio', 17 | display_name='DevTools Portfolio', 18 | description='Portfolio with approved list of developer tools products', 19 | provider_name='Central Admin Team') 20 | 21 | 22 | #Create a sample Service Catalog product 23 | product = sc.CloudFormationProduct(self, "S3SampleStack", 24 | product_name="S3CDKStack", 25 | owner="Storage Team", 26 | product_versions=[ 27 | sc.CloudFormationProductVersion( 28 | cloud_formation_template=sc.CloudFormationTemplate.from_product_stack(S3BucketProduct(self, "S3Product")), 29 | product_version_name="1.0", 30 | description="Deploys an S3 Bucket", 31 | ) 32 | ]) 33 | 34 | tag_options_for_product = sc.TagOptions(self, "ProductTagOptions", 35 | allowed_values_for_tags={ 36 | "Environment": ["dev", "alpha", "prod"] 37 | } 38 | ) 39 | 40 | product.associate_tag_options(tag_options_for_product) 41 | 42 | # Associate product to the portfolio 43 | portfolio.add_product(product) 44 | 45 | 46 | class S3BucketProduct(sc.ProductStack): 47 | def __init__(self, scope, id): 48 | super().__init__(scope, id) 49 | s3.Bucket(self, "ServiceCatalogTestBucket") 50 | 51 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/cfn_templates/config_rules/opa-ebs-encryption.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: Custom Config rule based on OPA policy to evaluate encryption of EBS volumes 3 | 4 | Parameters: 5 | AssetsBucket: 6 | Description: S3 bucket name where the OPA policy is stored 7 | Type: String 8 | ConfigRuleScope: 9 | Description: Scope of the Config rule. Comma delimited list of AWS resource types 10 | Type: CommaDelimitedList 11 | Default: AWS::EC2::Volume 12 | OpaPoliciesS3Prefix: 13 | Description: S3 key prefix where rego policies are stored. (e.g. opa_policies/) 14 | Type: String 15 | Default: opa_policies/ 16 | OpaPolicyS3Key: 17 | Description: S3 Key for OPA policy 18 | Type: String 19 | Default: opa_policy_ebs_encryption.rego 20 | OpaPolicyPackageName: 21 | Description: The package name from your OPA policy written in Rego 22 | Type: String 23 | Default: ebs_encryption 24 | OpaPolicyRuleToEval: 25 | Description: The rule from your OPA policy which will be evaluated 26 | Type: String 27 | Default: compliant 28 | 29 | Resources: 30 | OpaConfigRule: 31 | Type: AWS::Config::ConfigRule 32 | Properties: 33 | InputParameters: 34 | ASSETS_BUCKET: !Ref AssetsBucket 35 | REGO_POLICIES_PREFIX: !Ref OpaPoliciesS3Prefix 36 | REGO_POLICY_KEY: !Ref OpaPolicyS3Key 37 | OPA_POLICY_PACKAGE_NAME: !Ref OpaPolicyPackageName 38 | OPA_POLICY_RULE_TO_EVAL: !Ref OpaPolicyRuleToEval 39 | Scope: 40 | ComplianceResourceTypes: !Ref ConfigRuleScope 41 | Source: 42 | Owner: CUSTOM_LAMBDA 43 | SourceDetails: 44 | - EventSource: aws.config 45 | MessageType: ConfigurationItemChangeNotification 46 | SourceIdentifier: !ImportValue opa-lambda-arn 47 | 48 | Outputs: 49 | ConfigRuleName: 50 | Description: Name of the Config rule deployed 51 | Value: !Ref OpaConfigRule -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/cfn_templates/config_rules/opa-eip-attachment.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: Custom Config rule based on OPA policy to evaluate Elastic IP attachment status 3 | 4 | Parameters: 5 | AssetsBucket: 6 | Description: S3 bucket name where the OPA policy is stored 7 | Type: String 8 | ConfigRuleScope: 9 | Description: Scope of the Config rule. Comma delimited list of AWS resource types 10 | Type: CommaDelimitedList 11 | Default: AWS::EC2::EIP 12 | OpaPoliciesS3Prefix: 13 | Description: S3 key prefix where rego policies are stored. (e.g. opa_policies/) 14 | Type: String 15 | Default: opa_policies/ 16 | OpaPolicyS3Key: 17 | Description: S3 Key for OPA policy 18 | Type: String 19 | Default: opa_policy_eip_attachment.rego 20 | OpaPolicyPackageName: 21 | Description: The package name from your OPA policy written in Rego 22 | Type: String 23 | Default: eip_attachment 24 | OpaPolicyRuleToEval: 25 | Description: The rule from your OPA policy which will be evaluated 26 | Type: String 27 | Default: compliant 28 | 29 | Resources: 30 | OpaConfigRule: 31 | Type: AWS::Config::ConfigRule 32 | Properties: 33 | InputParameters: 34 | ASSETS_BUCKET: !Ref AssetsBucket 35 | REGO_POLICIES_PREFIX: !Ref OpaPoliciesS3Prefix 36 | REGO_POLICY_KEY: !Ref OpaPolicyS3Key 37 | OPA_POLICY_PACKAGE_NAME: !Ref OpaPolicyPackageName 38 | OPA_POLICY_RULE_TO_EVAL: !Ref OpaPolicyRuleToEval 39 | Scope: 40 | ComplianceResourceTypes: !Ref ConfigRuleScope 41 | Source: 42 | Owner: CUSTOM_LAMBDA 43 | SourceDetails: 44 | - EventSource: aws.config 45 | MessageType: ConfigurationItemChangeNotification 46 | SourceIdentifier: !ImportValue opa-lambda-arn 47 | 48 | Outputs: 49 | ConfigRuleName: 50 | Description: Name of the Config rule deployed 51 | Value: !Ref OpaConfigRule -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/cfn_templates/config_rules/opa-ebs-attachment.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: Custom Config rule based on OPA policy to evaluate EBS volumes attachment status 3 | 4 | Parameters: 5 | AssetsBucket: 6 | Description: S3 bucket name where the OPA policy is stored 7 | Type: String 8 | ConfigRuleScope: 9 | Description: Scope of the Config rule. Comma delimited list of AWS resource types 10 | Type: CommaDelimitedList 11 | Default: AWS::EC2::Volume 12 | OpaPoliciesS3Prefix: 13 | Description: S3 key prefix where rego policies are stored. (e.g. opa_policies/) 14 | Type: String 15 | Default: opa_policies/ 16 | OpaPolicyS3Key: 17 | Description: S3 Key for OPA policy 18 | Type: String 19 | Default: opa_policy_ebs_attachment.rego 20 | OpaPolicyPackageName: 21 | Description: The package name from your OPA policy written in Rego 22 | Type: String 23 | Default: ebs_attachment 24 | OpaPolicyRuleToEval: 25 | Description: The rule from your OPA policy which will be evaluated 26 | Type: String 27 | Default: compliant 28 | 29 | Resources: 30 | OpaConfigRule: 31 | Type: AWS::Config::ConfigRule 32 | Properties: 33 | InputParameters: 34 | ASSETS_BUCKET: !Ref AssetsBucket 35 | REGO_POLICIES_PREFIX: !Ref OpaPoliciesS3Prefix 36 | REGO_POLICY_KEY: !Ref OpaPolicyS3Key 37 | OPA_POLICY_PACKAGE_NAME: !Ref OpaPolicyPackageName 38 | OPA_POLICY_RULE_TO_EVAL: !Ref OpaPolicyRuleToEval 39 | Scope: 40 | ComplianceResourceTypes: !Ref ConfigRuleScope 41 | Source: 42 | Owner: CUSTOM_LAMBDA 43 | SourceDetails: 44 | - EventSource: aws.config 45 | MessageType: ConfigurationItemChangeNotification 46 | SourceIdentifier: !ImportValue opa-lambda-arn 47 | 48 | Outputs: 49 | ConfigRuleName: 50 | Description: Name of the Config rule deployed 51 | Value: !Ref OpaConfigRule -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/cfn_templates/config_rules/opa-s3-encryption.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: Custom Config rule based on OPA policy to evaluate encryption of S3 buckets 3 | 4 | Parameters: 5 | AssetsBucket: 6 | Description: S3 bucket name where the OPA policy is stored 7 | Type: String 8 | ConfigRuleScope: 9 | Description: Scope of the Config rule. Comma delimited list of AWS resource types 10 | Type: CommaDelimitedList 11 | Default: AWS::S3::Bucket 12 | OpaPoliciesS3Prefix: 13 | Description: S3 key prefix where rego policies are stored. (e.g. opa_policies/) 14 | Type: String 15 | Default: opa_policies/ 16 | OpaPolicyS3Key: 17 | Description: S3 Key for Opa policy 18 | Type: String 19 | Default: opa_policy_s3_encryption.rego 20 | OpaPolicyPackageName: 21 | Description: The package name from your OPA policy written in Rego 22 | Type: String 23 | Default: s3_bucket_encryption 24 | OpaPolicyRuleToEval: 25 | Description: The rule from your OPA policy which will be evaluated 26 | Type: String 27 | Default: compliant 28 | 29 | Resources: 30 | OpaConfigRule: 31 | Type: AWS::Config::ConfigRule 32 | Properties: 33 | InputParameters: 34 | ASSETS_BUCKET: !Ref AssetsBucket 35 | REGO_POLICIES_PREFIX: !Ref OpaPoliciesS3Prefix 36 | REGO_POLICY_KEY: !Ref OpaPolicyS3Key 37 | OPA_POLICY_PACKAGE_NAME: !Ref OpaPolicyPackageName 38 | OPA_POLICY_RULE_TO_EVAL: !Ref OpaPolicyRuleToEval 39 | Scope: 40 | ComplianceResourceTypes: !Ref ConfigRuleScope 41 | Source: 42 | Owner: CUSTOM_LAMBDA 43 | SourceDetails: 44 | - EventSource: aws.config 45 | MessageType: ConfigurationItemChangeNotification 46 | SourceIdentifier: !ImportValue opa-lambda-arn 47 | 48 | Outputs: 49 | ConfigRuleName: 50 | Description: Name of the Config rule deployed 51 | Value: !Ref OpaConfigRule -------------------------------------------------------------------------------- /AWSConfig/README.md: -------------------------------------------------------------------------------- 1 | ## AWS Config Samples 2 | 3 | This folder contains a collection of samples for AWS Config. The samples are designed to educate AWS customers on how to implement management and governance services. They are organized by various sample for AWS Config, although some of the samples maybe be leveraging multiple services. 4 | 5 | ## References 6 | 7 | The following links will provide additional resources to learn more around AWS Config. 8 | 9 | - [Webinar – Cloud Compliance and Assurance](https://pages.awscloud.com/Cloud-Compliance-and-Assurance_2021_0412-MGT_OD.html?&trk=ep_card-el_a131L0000084iG2QAI&trkCampaign=NA-FY21-AWS-DIGMKT-WEBINAR-SERIES-GC-500-GRO-MNGGOV-April_2021_0412-MGT&sc_channel=el&sc_campaign=pac_2018-2021_exlinks_ondemand_OTT_evergreen&sc_outcome=Product_Adoption_Campaigns&sc_geo=NAMER&sc_country=mult) 10 | - [DevSecOps for auto-healing PCI Compliance in AWS](https://aws.amazon.com/blogs/mt/devsecops-auto-healing-pci-dss-3-2-1-violations-aws-using-custom-aws-config-conformance-packs-aws-systems-manager-aws-codepipeline/) 11 | - [AWS Reference Solution - Cloud Compliance and Assurance](https://github.com/aws-samples/aws-cloud-compliance-assurance) 12 | - [Visualize Config data using Amazon Athena and Quicksight](https://aws.amazon.com/blogs/mt/visualizing-aws-config-data-using-amazon-athena-and-amazon-quicksight/) 13 | - [Standardize compliance in AWS using DevOps and CCOE approach](https://aws.amazon.com/blogs/mt/standardize-compliance-in-aws-using-devops-and-a-cloud-center-of-excellence-ccoe-approach/) 14 | - [Automate configuration compliance at scale in AWS](https://aws.amazon.com/blogs/mt/automate-configuration-compliance-at-scale-in-aws/) 15 | - [Integrate across the Three Lines Model](https://aws.amazon.com/blogs/mt/integrate-across-the-three-lines-model-part-2-transform-aws-config-conformance-packs-into-aws-audit-manager-assessments/) 16 | 17 | ## Security 18 | 19 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 20 | 21 | ## License 22 | 23 | This library is licensed under the MIT-0 License. See the LICENSE file. 24 | 25 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/host-management-examples/host-mgmt-cfn-template.yaml: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | #------------------------------------------------------------------------------ 20 | # 21 | # Template: host-mgmt-cfn-template.yaml 22 | # Purpose: CloudFormation template to deploy a Quick Setup configuration for Host Management. 23 | # 24 | #------------------------------------------------------------------------------ 25 | 26 | AWSTemplateFormatVersion: '2010-09-09' 27 | Description: CloudFormation template to deploy a Quick Setup configuration for Host Management. 28 | Resources: 29 | SSMQuickSetupTestConfigurationManager: 30 | Type: AWS::SSMQuickSetup::ConfigurationManager 31 | Properties: 32 | Name: qs-host-management 33 | Description: Enable Host Management for the AWS Organization 34 | ConfigurationDefinitions: 35 | - Type: AWSQuickSetupType-SSMHostMgmt 36 | Parameters: 37 | CollectInventory: 'true' 38 | ScanInstances: 'false' 39 | UpdateSsmAgent: 'false' 40 | TargetType: "*" 41 | TargetOrganizationalUnits: ou-ab12-cdefgh34 42 | TargetRegions: us-east-1,us-east-2 -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/dhmc-examples/dhmc-cfn-template.yaml: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | #------------------------------------------------------------------------------ 20 | # 21 | # Template: dhmc-cfn-template.yaml 22 | # Purpose: CloudFormation template to deploy a Quick Setup configuration for Default Host Management Configuration. 23 | # 24 | #------------------------------------------------------------------------------ 25 | 26 | AWSTemplateFormatVersion: '2010-09-09' 27 | Description: CloudFormation template to deploy a Quick Setup configuration for Default Host Management Configuration. 28 | Resources: 29 | DHMCQuickSetupConfigurationManager: 30 | Type: AWS::SSMQuickSetup::ConfigurationManager 31 | Properties: 32 | Name: qs-dhmc 33 | Description: Enable Default Host Management configuration for the AWS Organization 34 | ConfigurationDefinitions: 35 | - Type: AWSQuickSetupType-DHMC 36 | Parameters: 37 | UpdateSSMAgent: 'true' 38 | TargetOrganizationalUnits: r-1abc 39 | TargetRegions: eu-north-1, ap-south-1, eu-west-3, us-east-2, eu-west-1, eu-central-1, 40 | sa-east-1, us-east-1, ap-northeast-2, eu-west-2, ap-northeast-1, us-west-2, 41 | us-west-1, ap-southeast-1, ap-southeast-2, ca-central-1 -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-child-account/README.md: -------------------------------------------------------------------------------- 1 | # ssm-child-account 2 | 3 | This project directory includes the following files and folders: 4 | 5 | - * **template.yaml** - CloudFormation template to deploy resources into the child account containing your SSM Documents 6 | 7 | ## Deployment Instructions 8 | 9 | **Required parameters**: 10 | 11 | * **SNSTopicArn**: The SNS Topic ARN resource deployed into the AWS Organizations Management account. This SNS Topic ARN is found in the Output section in the CloudFormation stack that was created in your AWS Organizations Management account. 12 | * **SNSTopicRegion**: The region the SNS Topic was deployed to 13 | 14 | **Deployment** 15 | To deploy this template via CloudFormation StackSets, please refer to the CloudFormation StackSet documentation available at this url: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html#stacksets-getting-started-create-self-managed 16 | 17 | **Note** *This step assumes you already have created self-managed execution roles. If you have not created these roles yet, refer to the documentation here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs-self-managed.html. If you intend to deploy this to more than one child account or are using the CloudFormation StackSet service-managed role, you will need to update the SNS access policy in the management account to include all child account IDs.* 18 | 19 | To deploy this template to your preferred AWS Organization child account and region(s) via CloudFormation Stack, please refer to the CloudFormation documentation available at this url: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html 20 | 21 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit. 22 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started. 23 | 24 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 25 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 26 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) 27 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html) 28 | 29 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,node,linux,windows 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### Node ### 20 | # Logs 21 | logs 22 | *.log 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # Runtime data 28 | pids 29 | *.pid 30 | *.seed 31 | *.pid.lock 32 | 33 | # Directory for instrumented libs generated by jscoverage/JSCover 34 | lib-cov 35 | 36 | # Coverage directory used by tools like istanbul 37 | coverage 38 | 39 | # nyc test coverage 40 | .nyc_output 41 | 42 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | bower_components 47 | 48 | # node-waf configuration 49 | .lock-wscript 50 | 51 | # Compiled binary addons (http://nodejs.org/api/addons.html) 52 | build/Release 53 | 54 | # Dependency directories 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Typescript v1 declaration files 59 | typings/ 60 | 61 | # Optional npm cache directory 62 | .npm 63 | 64 | # Optional eslint cache 65 | .eslintcache 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variables file 77 | .env 78 | 79 | 80 | ### OSX ### 81 | *.DS_Store 82 | .AppleDouble 83 | .LSOverride 84 | 85 | # Icon must end with two \r 86 | Icon 87 | 88 | # Thumbnails 89 | ._* 90 | 91 | # Files that might appear in the root of a volume 92 | .DocumentRevisions-V100 93 | .fseventsd 94 | .Spotlight-V100 95 | .TemporaryItems 96 | .Trashes 97 | .VolumeIcon.icns 98 | .com.apple.timemachine.donotpresent 99 | 100 | # Directories potentially created on remote AFP share 101 | .AppleDB 102 | .AppleDesktop 103 | Network Trash Folder 104 | Temporary Items 105 | .apdisk 106 | 107 | ### Windows ### 108 | # Windows thumbnail cache files 109 | Thumbs.db 110 | ehthumbs.db 111 | ehthumbs_vista.db 112 | 113 | # Folder config file 114 | Desktop.ini 115 | 116 | # Recycle Bin used on file shares 117 | $RECYCLE.BIN/ 118 | 119 | # Windows Installer files 120 | *.cab 121 | *.msi 122 | *.msm 123 | *.msp 124 | 125 | # Windows shortcuts 126 | *.lnk 127 | 128 | 129 | # End of https://www.gitignore.io/api/osx,node,linux,windows -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/README.md: -------------------------------------------------------------------------------- 1 | # Automate AWS Organizations SSM Document Share Permissions 2 | 3 | This project contains source code and supporting files for an event-driven serverless application that you can deploy with the SAM CLI and CloudFormation StackSets. Once deployed, the project will trigger a workflow each time a new account is added to an AWS Organizations via the CreateAccount or InviteAccountToOrganization API call. The workflow will add SSM Document share permissions for the newly added Account ID in a designated AWS Organizations child account and all specified region(s). 4 | 5 | The application uses several AWS resources, including an EventBridge Rule, Lambda functions, a Step Function State Machine, and an SNS topic. These resources are defined in two separate `template.yaml` files in the projects two subdirectories. You can update the template to add AWS resources through the same deployment process that updates your application code. A ReadMe.md is included in each subdirectory with deployment instructions. 6 | 7 | ![Example Dashboard](./docs/diagram.png) 8 | 9 | This project includes the following files and folders. 10 | 11 | - * **docs** - Directory containing supporting documents 12 | - * **ssm-management-account** - Directory containing the template and code to deploy resources in an AWS Organizations management account via SAM CLI 13 | - * **ssm-child-account** - Directory containing the template to deploy Lambda code via CloudFormation StackSets 14 | 15 | 16 | ## Deployment Instructions 17 | 18 | First, deploy the ssm-management-account resources into your AWS Organizations management account via the SAM CLI by following the README.md instructions in the ssm-management-account directory. 19 | 20 | Next, deploy the `template.yaml` file in the ssm-child-account directory to the AWS Account in your AWS Organization that contains your SSM Documents. This `template.yaml` file can be deployed via CloudFormation StackSets or by manually deploying the CloudFormation Stack to your preferred account and region(s). 21 | 22 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit. 23 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started. 24 | 25 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 26 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 27 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) 28 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html) 29 | 30 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonCloudWatchLogs/LogInsightsUsage/templates/CWLogInsightsUsageDashboard/README.md: -------------------------------------------------------------------------------- 1 | # CloudWatch Custom Widget for Log Insights Query History 2 | 3 | ## Overview 4 | 5 | This CloudFormation template deploys an AWS Lambda function and an optional CloudWatch Dashboard to display a custom widget. The widget lists all the queries executed in CloudWatch Logs Insights in the last few days, ordered by the amount of bytes scanned. This is useful for identifying queries that scan a lot of data and may be candidates for optimization. 6 | 7 | ## Parameters 8 | 9 | - **DoCreateExampleDashboard**: 10 | - **Description**: Create the Dashboard to show the widget. Select `No` to deploy the Lambda function only. 11 | - **Type**: String 12 | - **Allowed Values**: `['Yes', 'No']` 13 | - **Default**: `Yes` 14 | 15 | ## Conditions 16 | 17 | - **CreateExampleDashboard**: This condition checks if `DoCreateExampleDashboard` is set to `Yes`. 18 | 19 | ## Resources 20 | 21 | ### Lambda Function 22 | 23 | - **Type**: `AWS::Lambda::Function` 24 | - **Properties**: 25 | - **Code**: Inline Python code that: 26 | - Obtains the current AWS region. 27 | - Uses the `boto3` library to interact with CloudWatch Logs. 28 | - Fetches and sorts query history by bytes scanned. 29 | - Generates an HTML table of the query history. 30 | - **Description**: "CloudWatch Custom Widget for Log Insights query history" 31 | - **FunctionName**: `${AWS::StackName}` 32 | - **Handler**: `index.lambda_handler` 33 | - **MemorySize**: `128` 34 | - **Role**: IAM Role with permissions to access CloudWatch Logs 35 | - **Runtime**: `python3.11` 36 | - **Timeout**: `60` seconds 37 | - **Tags**: 38 | - `Key`: `cw-custom-widget` 39 | - `Value`: `describe:readOnly` 40 | 41 | ### IAM Role for Lambda 42 | 43 | - **Type**: `AWS::IAM::Role` 44 | - **Properties**: 45 | - **AssumeRolePolicyDocument**: Allows Lambda to assume this role. 46 | - **Policies**: 47 | - Permissions to create log groups, streams, and put log events. 48 | - Permissions to describe and get query results from CloudWatch Logs. 49 | 50 | ### Log Group for Lambda 51 | 52 | - **Type**: `AWS::Logs::LogGroup` 53 | - **Properties**: 54 | - **LogGroupName**: `/aws/lambda/${AWS::StackName}` 55 | - **RetentionInDays**: `7` 56 | 57 | ### CloudWatch Dashboard (Optional) 58 | 59 | - **Type**: `AWS::CloudWatch::Dashboard` 60 | - **Condition**: `CreateExampleDashboard` 61 | - **Properties**: 62 | - **DashboardName**: `${AWS::StackName}-${AWS::Region}` 63 | - **DashboardBody**: JSON that includes a custom widget pointing to the Lambda function's ARN. 64 | 65 | ## Usage 66 | 67 | 1. **Deploy the Stack**: 68 | - Use the AWS Management Console, AWS CLI, or any other AWS SDK to deploy this CloudFormation template. 69 | 70 | 2. **View the Dashboard** (if created): 71 | - Navigate to the CloudWatch service in the AWS Management Console. 72 | - Open the dashboard named `${AWS::StackName}-${AWS::Region}` to view the custom widget. 73 | 74 | ## Notes 75 | 76 | - The Lambda function has a timeout of 60 seconds. Adjust this if your query history is extensive. 77 | - The log group retention is set to 7 days. Modify this as needed. 78 | 79 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/step-functions/state-machine.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment": "A sample state machine that queries CloudTrail Lake using the CloudtraillakeQuery Lambda function to demonstrate its capabilities.", 3 | "StartAt": "CloudtraillakeQuery_RequestServiceQuotaIncrease", 4 | "States": { 5 | "CloudtraillakeQuery_RequestServiceQuotaIncrease": { 6 | "Type": "Task", 7 | "Resource": "arn:aws:states:::lambda:invoke", 8 | "Parameters": { 9 | "FunctionName": "PLACEHOLDER", 10 | "Payload": { 11 | "EventDataStore": "PLACEHOLDER", 12 | "QueryStatement": "SELECT json_extract_scalar(element_at(responseElements, 'requestedQuota'), '$.id') as requestId, awsRegion, recipientAccountId FROM {m[EventDataStore]} WHERE eventSource='servicequotas.amazonaws.com' and eventname = 'RequestServiceQuotaIncrease'" 13 | } 14 | }, 15 | "Retry": [ 16 | { 17 | "ErrorEquals": [ 18 | "Lambda.ServiceException", 19 | "Lambda.AWSLambdaException", 20 | "Lambda.SdkClientException" 21 | ], 22 | "IntervalSeconds": 2, 23 | "MaxAttempts": 6, 24 | "BackoffRate": 2 25 | } 26 | ], 27 | "Next": "Each_RequestServiceQuotaIncrease" 28 | }, 29 | "Each_RequestServiceQuotaIncrease": { 30 | "Type": "Map", 31 | "End": true, 32 | "Iterator": { 33 | "StartAt": "CloudtraillakeQuery_UpdateServiceQuotaIncreaseRequestStatus", 34 | "States": { 35 | "CloudtraillakeQuery_UpdateServiceQuotaIncreaseRequestStatus": { 36 | "Type": "Task", 37 | "Resource": "arn:aws:states:::lambda:invoke", 38 | "Parameters": { 39 | "FunctionName": "PLACEHOLDER", 40 | "Payload": { 41 | "EventDataStore": "PLACEHOLDER", 42 | "QueryStatement": "SELECT recipientAccountId, awsRegion, serviceEventDetails FROM {m[EventDataStore]} WHERE eventSource='servicequotas.amazonaws.com' and eventname = 'UpdateServiceQuotaIncreaseRequestStatus' and element_at(serviceEventDetails, 'requestId') = '{m[RequestId]}'", 43 | "QueryFormatParams": { 44 | "RequestId.$": "$[0].requestId" 45 | } 46 | } 47 | }, 48 | "Retry": [ 49 | { 50 | "ErrorEquals": [ 51 | "Lambda.ServiceException", 52 | "Lambda.AWSLambdaException", 53 | "Lambda.SdkClientException" 54 | ], 55 | "IntervalSeconds": 2, 56 | "MaxAttempts": 6, 57 | "BackoffRate": 2 58 | } 59 | ], 60 | "Next": "Send_Report" 61 | }, 62 | "Send_Report": { 63 | "Type": "Task", 64 | "Resource": "arn:aws:states:::sns:publish", 65 | "Parameters": { 66 | "Message": { 67 | "ServiceLimitIncreaseStatus.$": "$.Payload.body[0]" 68 | }, 69 | "TopicArn": "PLACEHOLDER" 70 | }, 71 | "End": true 72 | } 73 | } 74 | }, 75 | "ItemsPath": "$.Payload.body" 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/lambda/cloudtraillake-query.py: -------------------------------------------------------------------------------- 1 | import json 2 | import boto3 3 | import time 4 | import re 5 | import datetime 6 | import os 7 | client = boto3.client('cloudtrail') 8 | RequiredParameters = ['EventDataStore', 'QueryStatement'] 9 | MaxQueryResults = 100 10 | 11 | def lambda_handler(event, context): 12 | 13 | # check the input parameters from the function invocation 14 | for requiredParam in RequiredParameters: 15 | if requiredParam not in event: 16 | return { 17 | 'statusCode': 400, 18 | 'body': json.dumps({ 19 | "MissingParameter": requiredParam 20 | }) 21 | } 22 | EventDataStore = event['EventDataStore'] 23 | QueryStatement = event['QueryStatement'] 24 | 25 | # obtain the event data store associated with this Lambda function if not provided 26 | if EventDataStore == '' or EventDataStore == "FROM_ENV": 27 | EventDataStore = os.environ['EVENT_DATA_STORE'] 28 | 29 | # If a full Arn was passed, we only need the event data store ID 30 | matchEDS = re.search("^arn:.*eventdatastore\/(.*)", EventDataStore) 31 | if matchEDS: 32 | EventDataStore = matchEDS.group(1) 33 | 34 | # insert the EventDataStore into the QueryFormatParams if used m{EventDataStore} in place of hard coding it into the QueryStatement 35 | # if eventDataStore is derived from the environment, then it will be formatted in to the SQL 36 | if not 'QueryFormatParams' in event: 37 | event['QueryFormatParams'] = {} 38 | if not 'EventDataStore' in event['QueryFormatParams']: 39 | event['QueryFormatParams']['EventDataStore'] = EventDataStore 40 | 41 | # further manipulate the QueryStatement if the caller passed in parameters to format into the query 42 | # note the format is {m[VariableName]} 43 | # for example: 44 | # "QueryStatement": "SELECT eventID, eventName, eventSource, eventTime FROM {m[EventDataStore]} WHERE ... 45 | # "QueryFormatParams" : { 46 | # "EventDataStore": "996f9246-56ad-49eb-bdd2-7276a6d17884", 47 | # "invalidParams": "will not be inserted" 48 | #} 49 | if 'QueryFormatParams' in event: 50 | QueryStatement = QueryStatement.format(m=event['QueryFormatParams']) 51 | 52 | # start the query 53 | response = client.start_query( 54 | QueryStatement=QueryStatement 55 | ) 56 | QueryId = response['QueryId'] 57 | 58 | # begin getting query results 59 | QueryResultRows = [] 60 | NextToken = None 61 | 62 | while 1: 63 | 64 | # get the batch of query results 65 | args = {} 66 | args['EventDataStore'] = EventDataStore 67 | args['QueryId'] = QueryId 68 | args['MaxQueryResults'] = MaxQueryResults 69 | if NextToken is not None: 70 | args['NextToken'] = NextToken 71 | response = client.get_query_results(**args) 72 | 73 | # handle if query is not yet finished 74 | if response['QueryStatus'] != 'FINISHED': 75 | time.sleep(1) 76 | continue 77 | 78 | # save the results and continue getting results if any 79 | if 'QueryResultRows' in response: 80 | QueryResultRows.extend(response['QueryResultRows']) 81 | if 'NextToken' in response: 82 | NextToken=response['NextToken'] 83 | else: 84 | break 85 | 86 | print("CloudTrail Lake Query:", { "TotalResults": len(QueryResultRows), "QueryStatement": QueryStatement, "EventDataStore": EventDataStore } ) 87 | 88 | return { 89 | 'statusCode': 200, 90 | 'body': QueryResultRows 91 | } 92 | 93 | -------------------------------------------------------------------------------- /AWSConfig/ConformancePacks/CP-Prerequisites.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: This is a quick start cloudformation template for AWS Config Conformance packs. It will create all the necessary resource to start using Conformance Packs one AWS Account. That is the service linked role, bucket and bucket policy 3 | Parameters: 4 | CreateServiceLinkedRole: 5 | Description: >- 6 | Specify if the service linked role should be created as part of the 7 | deployment of the stack. 8 | Default: true 9 | Type: String 10 | AllowedValues: 11 | - true 12 | - false 13 | ConstraintDescription: Must specify weather to create the service linked role or not. 14 | CPBucketName: 15 | Type: String 16 | Description: >- 17 | Enter the name of the bucket that will be used to deliver the conformance 18 | pack evaluation results 19 | Conditions: 20 | CreateSLR: !Equals 21 | - !Ref CreateServiceLinkedRole 22 | - true 23 | Resources: 24 | CPDeliveryS3Bucket: 25 | Type: 'AWS::S3::Bucket' 26 | Properties: 27 | BucketName: !Ref CPBucketName 28 | VersioningConfiguration: 29 | Status: Enabled 30 | BucketEncryption: 31 | ServerSideEncryptionConfiguration: 32 | - ServerSideEncryptionByDefault: 33 | SSEAlgorithm: AES256 34 | 35 | CPBucketPolicy: 36 | Type: 'AWS::S3::BucketPolicy' 37 | Properties: 38 | Bucket: !Ref CPDeliveryS3Bucket 39 | PolicyDocument: 40 | Statement: 41 | - Sid: AWSConfigConformsBucketPermissionsCheck 42 | Effect: Allow 43 | Principal: 44 | AWS: !Join 45 | - '' 46 | - - 'arn:aws:iam::' 47 | - !Ref 'AWS::AccountId' 48 | - ':role/aws-service-role/config-conforms.amazonaws.com/' 49 | - AWSServiceRoleForConfigConforms 50 | Action: 's3:GetBucketAcl' 51 | Resource: !Join 52 | - '' 53 | - - 'arn:aws:s3:::' 54 | - !Ref CPDeliveryS3Bucket 55 | - Sid: AWSConfigConformsBucketDelivery 56 | Effect: Allow 57 | Principal: 58 | AWS: !Join 59 | - '' 60 | - - 'arn:aws:iam::' 61 | - !Ref 'AWS::AccountId' 62 | - >- 63 | :role/aws-service-role/config-conforms.amazonaws.com/AWSServiceRoleForConfigConforms 64 | Action: 's3:PutObject' 65 | Resource: !Join 66 | - '' 67 | - - 'arn:aws:s3:::' 68 | - !Ref CPDeliveryS3Bucket 69 | - /AWSLogs/ 70 | - !Ref 'AWS::AccountId' 71 | - /Config/* 72 | Condition: 73 | StringEquals: 74 | 's3:x-amz-acl': 75 | - bucket-owner-full-control 76 | - Sid: ' AWSConfigConformsBucketReadAccess' 77 | Effect: Allow 78 | Principal: 79 | AWS: !Join 80 | - '' 81 | - - 'arn:aws:iam::' 82 | - !Ref 'AWS::AccountId' 83 | - >- 84 | :role/aws-service-role/config-conforms.amazonaws.com/AWSServiceRoleForConfigConforms 85 | Action: 's3:GetObject' 86 | Resource: !Join 87 | - '' 88 | - - 'arn:aws:s3:::' 89 | - !Ref CPDeliveryS3Bucket 90 | - /AWSLogs/ 91 | - !Ref 'AWS::AccountId' 92 | - /Config/* 93 | CPSerciceLinkedRole: 94 | Type: 'AWS::IAM::ServiceLinkedRole' 95 | Condition: CreateSLR 96 | Properties: 97 | AWSServiceName: config-conforms.amazonaws.com 98 | Description: Service Linked Role for Conformance Pack Deployment 99 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/cfn_templates/lambda_backend/opa-lambda.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: AWS Lambda function backing custom Config rules for OPA policy evaluation 3 | 4 | Parameters: 5 | AssetsBucket: 6 | Description: S3 bucket name where the Lambda sources are stored 7 | Type: String 8 | LambdaAssetsS3Prefix: 9 | Description: S3 key prefix where lambda layer files are stored. (e.g. packaged_lambda_assets/) 10 | Type: String 11 | Default: packaged_lambda_assets/ 12 | LambdaLayerS3Key: 13 | Description: S3 Key for lambda layer archive 14 | Type: String 15 | Default: opa.zip 16 | LambdaSourcesS3Key: 17 | Description: S3 Key for lambda function source code 18 | Type: String 19 | Default: sources.zip 20 | LambdaLoggingLevel: 21 | Default: DEBUG 22 | Description: Python logging level for Lambda functions 23 | Type: String 24 | LayerBinaryPath: 25 | Default: /opt/opa/bin 26 | Description: Filesystem path for OPA binary 27 | Type: String 28 | LayerLibrariesPath: 29 | Default: /opt/opa/lib 30 | Description: Filesystem path for shared libraries 31 | Type: String 32 | 33 | Resources: 34 | LambdaRole: 35 | Type: AWS::IAM::Role 36 | Properties: 37 | AssumeRolePolicyDocument: 38 | Version: 2012-10-17 39 | Statement: 40 | - Effect: Allow 41 | Principal: 42 | Service: 43 | - lambda.amazonaws.com 44 | Action: 45 | - sts:AssumeRole 46 | Path: / 47 | Policies: 48 | - PolicyName: root 49 | PolicyDocument: 50 | Version: 2012-10-17 51 | Statement: 52 | - Effect: Allow 53 | Action: 54 | - s3:GetObject* 55 | Resource: !Sub 'arn:${AWS::Partition}:s3:::${AssetsBucket}/*' 56 | - Effect: Allow 57 | Action: config:PutEvaluations 58 | Resource: '*' 59 | - Effect: Allow 60 | Action: 61 | - logs:CreateLogGroup 62 | Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:*' 63 | - Effect: Allow 64 | Action: 65 | - logs:CreateLogStream 66 | - logs:PutLogEvents 67 | Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*' 68 | 69 | LambdaFunction: 70 | Type: AWS::Lambda::Function 71 | Properties: 72 | Handler: opa_lambda.lambda_handler 73 | Role: !GetAtt LambdaRole.Arn 74 | Runtime: python3.8 75 | Timeout: 600 76 | Code: 77 | S3Bucket: !Ref AssetsBucket 78 | S3Key: !Sub '${LambdaAssetsS3Prefix}${LambdaSourcesS3Key}' 79 | Environment: 80 | Variables: 81 | LOGGING_LEVEL: !Ref LambdaLoggingLevel 82 | LD_LIBRARY_PATH: !Sub '$LD_LIBRARY_PATH:${LayerLibrariesPath}' 83 | PATH: !Sub '$PATH:${LayerBinaryPath}' 84 | Layers: 85 | - !Ref OpaLayer 86 | 87 | LambdaInvokePermissionsForConfig: 88 | Type: AWS::Lambda::Permission 89 | Properties: 90 | FunctionName: !GetAtt LambdaFunction.Arn 91 | Action: lambda:InvokeFunction 92 | Principal: config.amazonaws.com 93 | 94 | OpaLayer: 95 | Type: AWS::Lambda::LayerVersion 96 | Properties: 97 | CompatibleRuntimes: 98 | - python3.6 99 | - python3.10 100 | - python3.8 101 | Content: 102 | S3Bucket: !Ref AssetsBucket 103 | S3Key: !Sub '${LambdaAssetsS3Prefix}${LambdaLayerS3Key}' 104 | Description: OPA layer for custom Config rules lambda 105 | LayerName: opa-layer 106 | 107 | Outputs: 108 | LambdaArn: 109 | Description: The ARN of the Lambda function 110 | Value: !GetAtt LambdaFunction.Arn 111 | Export: 112 | Name: opa-lambda-arn -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/archive/step-function-s3-audit.json: -------------------------------------------------------------------------------- 1 | { "overrides": { 2 | "CloudtraillakeQuery_first": { 3 | "Parameters": { 4 | "FunctionName": handler.functionArn, 5 | "Payload": { 6 | "EventDataStore": eventDataStoreId, 7 | "QueryFormatParams": { 8 | "EventDataStore": eventDataStoreId, 9 | "EventName": "CreateBucket" 10 | } 11 | } 12 | } 13 | }, 14 | "Each_CreateBucket": { 15 | "Iterator": { 16 | "States" : { 17 | "CloudtraillakeQuery_second": { 18 | "Parameters": { 19 | "FunctionName": handler.functionArn, 20 | "Payload": { 21 | "EventDataStore": eventDataStoreId, 22 | "QueryFormatParams": { 23 | "EventDataStore": eventDataStoreId 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | }, 32 | { 33 | "Comment": "A sample state machine that queries CloudTrail Lake using the CloudtraillakeQuery Lambda function to demonstrate its capabilities.", 34 | "StartAt": "CloudtraillakeQuery_first", 35 | "States": { 36 | "CloudtraillakeQuery_first": { 37 | "Type": "Task", 38 | "Resource": "arn:aws:states:::lambda:invoke", 39 | "Parameters": { 40 | "FunctionName": "PLACEHOLDER", 41 | "Payload": { 42 | "EventDataStore": "PLACEHOLDER", 43 | "QueryStatement": "SELECT userIdentity.principalid, eventTime FROM {m[EventDataStore]} WHERE userIdentity.principalid IS NOT NULL AND eventName='{m[EventName]}'", 44 | "QueryFormatParams": { 45 | "EventDataStore": "PLACEHOLDER", 46 | "EventName": "PLACEHOLDER" 47 | } 48 | } 49 | }, 50 | "Retry": [ 51 | { 52 | "ErrorEquals": [ 53 | "Lambda.ServiceException", 54 | "Lambda.AWSLambdaException", 55 | "Lambda.SdkClientException" 56 | ], 57 | "IntervalSeconds": 2, 58 | "MaxAttempts": 6, 59 | "BackoffRate": 2 60 | } 61 | ], 62 | "Next": "Each_CreateBucket" 63 | }, 64 | "Each_CreateBucket": { 65 | "Type": "Map", 66 | "Iterator": { 67 | "StartAt": "CloudtraillakeQuery_second", 68 | "States": { 69 | "CloudtraillakeQuery_second": { 70 | "Type": "Task", 71 | "Resource": "arn:aws:states:::lambda:invoke", 72 | "Parameters": { 73 | "FunctionName": "PLACEHOLDER", 74 | "Payload": { 75 | "EventDataStore": "PLACEHOLDER", 76 | "QueryStatement": "SELECT eventID, eventName, eventSource, eventTime FROM {m[EventDataStore]} WHERE eventTime > '{m[EventStartTime]}' AND eventSource = 's3.amazonaws.com' AND userIdentity.principalid = '{m[UserPrincipalId]}'", 77 | "QueryFormatParams": { 78 | "EventDataStore": "PLACEHOLDER", 79 | "EventStartTime.$": "$[1].eventTime", 80 | "UserPrincipalId.$": "$[0].principalid" 81 | } 82 | } 83 | }, 84 | "Retry": [ 85 | { 86 | "ErrorEquals": [ 87 | "Lambda.ServiceException", 88 | "Lambda.AWSLambdaException", 89 | "Lambda.SdkClientException" 90 | ], 91 | "IntervalSeconds": 2, 92 | "MaxAttempts": 6, 93 | "BackoffRate": 2 94 | } 95 | ], 96 | "Next": "Send_Audit" 97 | }, 98 | "Send_Audit": { 99 | "Type": "Pass", 100 | "End": true, 101 | "Comment": "You might want to send the results from the CloudtraillakeQuery lambda function somewhere at this point." 102 | } 103 | } 104 | }, 105 | "ItemsPath": "$.Payload.body", 106 | "Next": "CloudtraillakeQuery_third" 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/patch-policy-examples/default-patch-baselines.txt: -------------------------------------------------------------------------------- 1 | $ aws ssm describe-patch-baselines |jq '.BaselineIdentities | map({ (.OperatingSystem): (.value = .BaselineId | .label = .BaselineName | .description = .BaselineDescription | .disabled=false | del(.BaselineId, .BaselineName, .OperatingSystem, .BaselineDescription, .DefaultBaseline)) }) | add' 2 | { 3 | "AMAZON_LINUX_2022": { 4 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0028ca011460d5eaf", 5 | "label": "AWS-AmazonLinux2022DefaultPatchBaseline", 6 | "description": "Default Patch Baseline for Amazon Linux 2022 Provided by AWS.", 7 | "disabled": false 8 | }, 9 | "CENTOS": { 10 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03e3f588eec25344c", 11 | "label": "AWS-CentOSDefaultPatchBaseline", 12 | "description": "Default Patch Baseline for CentOS Provided by AWS.", 13 | "disabled": false 14 | }, 15 | "ROCKY_LINUX": { 16 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03ec98bc512aa3ac0", 17 | "label": "AWS-RockyLinuxDefaultPatchBaseline", 18 | "description": "Default Patch Baseline for Rocky Linux Provided by AWS.", 19 | "disabled": false 20 | }, 21 | "AMAZON_LINUX_2023": { 22 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-05c9c9bf778d4c4d0", 23 | "label": "AWS-AmazonLinux2023DefaultPatchBaseline", 24 | "description": "Default Patch Baseline for Amazon Linux 2023 Provided by AWS.", 25 | "disabled": false 26 | }, 27 | "ORACLE_LINUX": { 28 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-06bff38e95fe85c02", 29 | "label": "AWS-OracleLinuxDefaultPatchBaseline", 30 | "description": "Default Patch Baseline for Oracle Linux Server Provided by AWS.", 31 | "disabled": false 32 | }, 33 | "SUSE": { 34 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-07d8884178197b66b", 35 | "label": "AWS-SuseDefaultPatchBaseline", 36 | "description": "Default Patch Baseline for Suse Provided by AWS.", 37 | "disabled": false 38 | }, 39 | "WINDOWS": { 40 | "value": "pb-016889927b2bb8542", 41 | "label": "custom-WindowsServer-Blog-Baseline", 42 | "description": null, 43 | "disabled": false 44 | }, 45 | "DEBIAN": { 46 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-09a5f8eb62bde80b1", 47 | "label": "AWS-DebianDefaultPatchBaseline", 48 | "description": "Default Patch Baseline for Debian Provided by AWS.", 49 | "disabled": false 50 | }, 51 | "AMAZON_LINUX_2": { 52 | "value": "pb-01134e599504910b5", 53 | "label": "custom-AmazonLinux2-Blog-Baseline", 54 | "description": null, 55 | "disabled": false 56 | }, 57 | "AMAZON_LINUX": { 58 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0c10e657807c7a700", 59 | "label": "AWS-AmazonLinuxDefaultPatchBaseline", 60 | "description": "Default Patch Baseline for Amazon Linux Provided by AWS.", 61 | "disabled": false 62 | }, 63 | "UBUNTU": { 64 | "value": "pb-06e3563bd35503f2b", 65 | "label": "custom-UbuntuServer-Blog-Baseline", 66 | "description": null, 67 | "disabled": false 68 | }, 69 | "ALMA_LINUX": { 70 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cb0c4966f86b059b", 71 | "label": "AWS-AlmaLinuxDefaultPatchBaseline", 72 | "description": "Default Patch Baseline for Alma Linux Provided by AWS.", 73 | "disabled": false 74 | }, 75 | "REDHAT_ENTERPRISE_LINUX": { 76 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cbb3a633de00f07c", 77 | "label": "AWS-RedHatDefaultPatchBaseline", 78 | "description": "Default Patch Baseline for Redhat Enterprise Linux Provided by AWS.", 79 | "disabled": false 80 | }, 81 | "RASPBIAN": { 82 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ec16280999c5c75e", 83 | "label": "AWS-RaspbianDefaultPatchBaseline", 84 | "description": "Default Patch Baseline for Raspbian Provided by AWS.", 85 | "disabled": false 86 | }, 87 | "MACOS": { 88 | "value": "arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ee4f94581368c0d4", 89 | "label": "AWS-MacOSDefaultPatchBaseline", 90 | "description": "Default Patch Baseline for MacOS Provided by AWS.", 91 | "disabled": false 92 | } 93 | } -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtrail-lake-analysis/README.md: -------------------------------------------------------------------------------- 1 | # Using Generative AI to Gain Insights into CloudTrail Lake Queries with CloudWatch Dashboards 2 | 3 | # Overview 4 | We recently highlighted in the blog “[**Using Generative AI to Gain Insights into CloudWatch Logs**](https://aws.amazon.com/blogs/mt/using-generative-ai-to-gain-insights-into-cloudwatch-logs/)” on how to use Bedrock to gain insights into your CloudWatch Log Groups. In the following sample solution, we will show you how to extend this sample solution to provide insights using generative AI for your CloudTrail Lake queries. 5 | 6 | The sample solution will allow you to create a custom widget that is backed by an AWS Lambda Function. When the dashboard is loaded, or refreshed, CloudWatch invokes the Lambda function to query CloudTrail Lake and send the results to Bedrock for analysis to then display the data it returns as a custom widget in the CloudWatch dashboard. 7 | 8 | **Note:** This sample solution is for demonstration purposes showing how you can use custom widgets to provide an analysis of your CloudTrail Lake query results using Bedrock for your CloudWatch Dashboards. 9 | 10 | # Costs: 11 | 12 | The costs associated with using this solution are from the CloudWatch dashboard, the custom widget, a Dynamo DB Table, CloudTrail Lake query and Bedrock. Custom widgets run Lambda code, and in this case the Lambda functions make API calls. The cost should be minimal, but you should still be mindful. As a best practice you can utilize AWS Budgets with Cost Allocation Tags to monitor costs. All pricing details are on the Amazon CloudWatch, AWS CloudTrail, AWS Lambda, DynamoDB, and Bedrock pricing pages. 13 | 14 | # Implementation Steps: 15 | ## Prerequisites: 16 | * Claude3 Haiku model access is required to generate the summaries. 17 | - Other models can be used, and would require access to the desired model, and modification of the Lambda function code to specify the model and send the information to the model in the correct format. 18 | 19 | ## Deploy the CloudFormation template to create the resources 20 | 21 | 1. Download the [yaml](./cfn/cfn_cloudtrail_lake_analysis.yaml) file. 22 | 1. Navigate to the CloudFormation console. 23 | 1. Choose **Create stack**. 24 | 1. Choose **Template is ready**, upload a template file, and navigate to the yaml file that you just downloaded. 25 | 1. Choose **Next**. 26 | 1. Give the stack a name, and select **Next**. 27 | 1. For the parameter **CloudTrail Lake Event data store ARN**, enter the ARN of your CloudTrail Lake Event data store. 28 | 1. Select **Next**. 29 | 1. Scroll to Capabilities at the bottom of the screen, and check the box **I acknowledge that AWS CloudFormation might create IAM resources with custom names**, and choose **Create stack**. 30 | 31 | ## Create a CloudWatch dashboard and add the custom widget 32 | 33 | 1. Next you need to Navigate to the CloudWatch console → **Create a Dashboard** -> Name your Dashboard. 34 | 1. An **“Add widget”** pop-up will open. Click on **“Other content types”** and select **“Custom widget”**. 35 | 36 | ![Widget Selection Menu](./images/widget_selection_staging.jpg) 37 | 38 | 1. Click on **“Next”**. 39 | 1. Choose **“Select a Lambda function“** and choose **“Select from a list”**. 40 | 1. Then, select the Lambda Function called **BedrockCloudTrailAnalysisFunction**. 41 | 1. Next, enter in the **cloudtrail_lake_query** and **cloudtrail_lake_query_name** in the yaml format in the input box under **“Parameters”** section of the widget configuration window. 42 | ![Completed Widget Configuration](./images/widget-config.png) 43 | 44 | **Optional:** You can also click on **“Get Documentation”** to see the format you need to pass the parameters for the function. 45 | 46 | ### YAML parameters format 47 | 48 | ```yaml 49 | cloudtrail_lake_query: "SELECT eventSource, eventName, COUNT(*) AS apiCount FROM $EDS_ID WHERE eventTime > DATE_ADD('week', -1, CURRENT_TIMESTAMP) GROUP BY eventSource, eventName ORDER BY apiCount DESC" 50 | 51 | cloudtrail_lake_query_name: "Top APIs aggregated by source" 52 | ``` 53 | 54 | 1. Click on **“Preview Widget”** to see the summary of your CloudTrail Lake Query. 55 | 56 | 1. Click on **“Add Widget”**, you will then see the custom widget appear on the dashboard. 57 | 58 | 1. Click on **“Save Dashboard”** to save the changes you made. 59 | 60 | # Clean Up: 61 | 62 | Delete the CloudFormation stack to terminate all resources. -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-Visualization/README.md: -------------------------------------------------------------------------------- 1 |

2 |

3 | 4 | ## AWS SSM Automation Runbook to Setup AWS Config with Amazon Athena and Amazon QuickSights 5 | This solution is based on the blog [Visualizing AWS Config data using Amazon Athena and Amazon QuickSight](https://aws.amazon.com/blogs/mt/visualizing-aws-config-data-using-amazon-athena-and-amazon-quicksight/). 6 | 7 | ### What does this cloudformation template do? 8 | This template will deploy a SSM Automation runbook called **Config-QuickSight-Visualization** that can be used to setup AWS Config to be used with Amazon Athena and setup Amazon Quicksights to be able to create visualize dashboards 9 | 10 | ## Running the Config-QuickSight-Visualization Automation Runbook 11 | 12 | ### Prerequisite 13 | 1. Configure [Delivering Configuration Snapshot to an Amazon S3 Bucket](https://docs.aws.amazon.com/config/latest/developerguide/deliver-snapshot-cli.html) for AWS. 14 | 1. Ensure access to your S3 Bucket that is used for AWS Config. 15 | 1. The S3 Bucket Name used with AWS Config. 16 | 1. [Amazon Quicksight Subscription](https://docs.aws.amazon.com/quicksight/latest/user/signing-up.html) enabled in your AWS Account. 17 | 1. Authorize [Amazon QuickSight access](https://docs.aws.amazon.com/quicksight/latest/user/athena.html) to the S3 bucket Athena will be using for AWS Config under Security and Permissions within Amazon Quicksights. 18 | 1. The Amazon Quicksight Username. 19 | 20 | ### Input Parameters for the Config-QuickSight-Visualization Automation Runbook 21 | * **ConfigDeliveryChannelName:** (Required) Name of your AWS Config Delievery Channel. The default is set to the value of default. 22 | * **ConfigS3BucketLocation:** (Required) AWS Config S3 Bucket Name, this is the name of your S3 Bucket you currently use for AWS Config. (ie config-bucket-1234567891) 23 | * **QuickSightUserName:** (Required) The Amazon QuickSight Username. 24 | * **AutomationAssumeRole:** (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. 25 | * **DeleteConfigVisualization:** (Optional) Set this to true if you would like to delete the resources created to enable this solution. The default is set to false which will setup the solution. 26 | 27 | ## Creating Visuals in Amazon QuickSight 28 | 29 | The **Config-QuickSight-Visualization** Automation Runbook will create the below views and datasets within Amazon Athena and Amazon QuickSight. You can then use these to create your visualization dashboard. 30 | 31 | * v_config_rules_compliance 32 | * v_config_resource_compliance 33 | * v_config_rds_dbinstances 34 | * v_config_iam_resources 35 | * v_config_ec2_vpcs 36 | * v_config_ec2_instances 37 | * v_config_resources 38 | 39 | #### Creating your Analyses in Amazon QuickSight 40 | 41 | 1. From Amazon QuickSight, choose **New analysis**. 42 | 1. On the **Datasets** page, choose the **v_config_resource_compliance** data set and then choose **Create Analysis**. 43 | 44 | #### Create a Visual By Using AutoGraph 45 | 46 | 1. Create a visual by using AutoGraph, which is selected by default. 47 | 1. On the analysis page, choose **accountid** and **compliancetype** in the Fields list pane. 48 | 1. Amazon QuickSight creates a **Horizontal bar chart** using this data. 49 | 50 | #### Adding Additional Datasets to your Analyses 51 | 52 | 1. You can add more data sets to the analysis to create more visuals. 53 | 1. From within the analysis, click the **Add,edit,replace and remove datasets** icon. 54 | 1. Click **Add Datasets**. 55 | 1. Select the **v_config_rules_compliance** and click **Select** 56 | 1. In the **Visual types** pane, choose the **Vertical Bar Chart** icon. 57 | 1. On the analysis page, choose **configrulename** and **compliancetype** in the Fields list pane. 58 | 1. You can create a filter on any field in the currently selected visual. When you create a filter, it applies by default to the currently selected visual only. 59 | 1. Click on the **Filter** icon within the Amazon QuickSight side bar. 60 | 1. Under the Filters section click "**Create one...**" and select the **configrulename** field. 61 | 1. Click on the **configrulename** field and uncheck the **Select all** check box. 62 | 1. Select a couple of Config Rules you would like to dispaly in your visual and clikc **Apply**. 63 | 1. You can then click on the **Visualize** button on the side bar to return to make changes to your visual. 64 | 65 | #### Create a Dashboard 66 | 67 | 1. In the analysis, choose **Share** in the application bar at upper-right, and then choose **Publish dashboard**. 68 | 1. In the **Publish dashboard** page that opens, choose **Publish new dashboard as**, and enter the name **Config Dashboard**. 69 | 1. Choose **Publish dashboard**. 70 | 1. On the **Share dashboard** page that opens, choose the **X** icon to close it. 71 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/patch-policy-examples/patch-policy-cli-input.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: qs-patch-policy 3 | Description: Enable Patch Policy for the AWS Organization 4 | ConfigurationDefinitions: 5 | - Type: AWSQuickSetupType-PatchPolicy 6 | LocalDeploymentAdministrationRoleArn: arn:aws:iam::123456789012:role/AWS-QuickSetup-StackSet-Local-AdministrationRole 7 | LocalDeploymentExecutionRoleName: AWS-QuickSetup-StackSet-Local-ExecutionRole 8 | Parameters: 9 | ConfigurationOptionsInstallNextInterval: 'true' 10 | ConfigurationOptionsInstallValue: cron(0 2 ? * SAT#1 *) 11 | ConfigurationOptionsPatchOperation: ScanAndInstall 12 | ConfigurationOptionsScanNextInterval: 'false' 13 | ConfigurationOptionsScanValue: cron(0 1 * * ? *) 14 | HasDeletedBaseline: 'false' 15 | IsPolicyAttachAllowed: 'true' 16 | OutputBucketRegion: '' 17 | OutputLogEnableS3: 'false' 18 | OutputS3BucketName: '' 19 | OutputS3KeyPrefix: '' 20 | PatchBaselineRegion: us-east-1 21 | PatchBaselineUseDefault: custom 22 | PatchPolicyName: dev-patch-policy 23 | RateControlConcurrency: '5' 24 | RateControlErrorThreshold: 0% 25 | RebootOption: RebootIfNeeded 26 | ResourceGroupName: '' 27 | SelectedPatchBaselines: '{"ALMA_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cb0c4966f86b059b","label":"AWS-AlmaLinuxDefaultPatchBaseline","description":"Default 28 | Patch Baseline for Alma Linux Provided by AWS.","disabled":false},"AMAZON_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0c10e657807c7a700","label":"AWS-AmazonLinuxDefaultPatchBaseline","description":"Default 29 | Patch Baseline for Amazon Linux Provided by AWS.","disabled":false},"AMAZON_LINUX_2":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0be8c61cde3be63f3","label":"AWS-AmazonLinux2DefaultPatchBaseline","description":"Baseline 30 | containing all Security and Bugfix updates approved for Amazon Linux 2 instances","disabled":false},"AMAZON_LINUX_2022":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0028ca011460d5eaf","label":"AWS-AmazonLinux2022DefaultPatchBaseline","description":"Default 31 | Patch Baseline for Amazon Linux 2022 Provided by AWS.","disabled":false},"AMAZON_LINUX_2023":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-05c9c9bf778d4c4d0","label":"AWS-AmazonLinux2023DefaultPatchBaseline","description":"Default 32 | Patch Baseline for Amazon Linux 2023 Provided by AWS.","disabled":false},"CENTOS":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03e3f588eec25344c","label":"AWS-CentOSDefaultPatchBaseline","description":"Default 33 | Patch Baseline for CentOS Provided by AWS.","disabled":false},"DEBIAN":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-09a5f8eb62bde80b1","label":"AWS-DebianDefaultPatchBaseline","description":"Default 34 | Patch Baseline for Debian Provided by AWS.","disabled":false},"MACOS":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ee4f94581368c0d4","label":"AWS-MacOSDefaultPatchBaseline","description":"Default 35 | Patch Baseline for MacOS Provided by AWS.","disabled":false},"ORACLE_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-06bff38e95fe85c02","label":"AWS-OracleLinuxDefaultPatchBaseline","description":"Default 36 | Patch Baseline for Oracle Linux Server Provided by AWS.","disabled":false},"RASPBIAN":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ec16280999c5c75e","label":"AWS-RaspbianDefaultPatchBaseline","description":"Default 37 | Patch Baseline for Raspbian Provided by AWS.","disabled":false},"REDHAT_ENTERPRISE_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cbb3a633de00f07c","label":"AWS-RedHatDefaultPatchBaseline","description":"Default 38 | Patch Baseline for Redhat Enterprise Linux Provided by AWS.","disabled":false},"ROCKY_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03ec98bc512aa3ac0","label":"AWS-RockyLinuxDefaultPatchBaseline","description":"Default 39 | Patch Baseline for Rocky Linux Provided by AWS.","disabled":false},"SUSE":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-07d8884178197b66b","label":"AWS-SuseDefaultPatchBaseline","description":"Default 40 | Patch Baseline for Suse Provided by AWS.","disabled":false},"UBUNTU":{"value":"pb-06e3563bd35503f2b","label":"custom-UbuntuServer-Blog-Baseline","description":"Default 41 | Patch Baseline for Ubuntu Provided by AWS.","disabled":false},"WINDOWS":{"value":"pb-016889927b2bb8542","label":"custom-WindowsServer-Blog-Baseline","disabled":false}}' 42 | TargetInstances: '' 43 | TargetOrganizationalUnits: ou-ab12-cdefgh34 44 | TargetRegions: us-east-1,us-east-2 45 | TargetTagKey: Patch 46 | TargetTagValue: 'true' 47 | TargetType: Tags 48 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to the CloudTrail Lake Orchestrator project 2 | 3 | This CDK project deploys a Lambda function which can be used to make querying CloudTrail Lake easier. 4 | It also deploys a sample Step Functions state machine which demonstrates how you can easily orchestrate 5 | your business logic. 6 | 7 | ## Sample state machine - AWS Service Limits 8 | 9 | The sample state machine will query AWS service limits for pending and resolved quota increases. This is a easy and quick way for customers to know which service limits were increased over a period of time across different regions and accounts. Currently customers have to login into each account and switch into each region and write down service quota history details on a piece of paper. Through the use of this solution along with CloudTrail Lake, the process can be automated. 10 | 11 | ## 3rd party npm package disclaimer 12 | 13 | This solution requires installing a 3rd party package that is not owned or maintained by AWS. The package is a CDK construct called "@matthewbonig/state-machine". You can ready about it [here](https://www.npmjs.com/package/@matthewbonig/state-machine) and in this [blog](https://matthewbonig.com/2022/02/19/step-functions-and-the-cdk/). Matthew was featured on episode 031 of the [AWS Developer Podcast](https://aws.amazon.com/developer/podcast/). 14 | 15 | ## Getting started 16 | 17 | 1. Create a CloudTrail Lake event data store from the [CloudTrail Lake console](https://console.aws.amazon.com/cloudtrailv2/home#/lake). Copy the event data store ARN from the Event data stores tab in the console. 18 | 2. [Optional] Create an AWS Cloud9 environment from the [AWS Cloud9 console](https://console.aws.amazon.com/cloud9/home) if you do not already have an environment for deploying CDK projects. 19 | 3. Check out this GitHub repository in your environment using `git clone` 20 | 4. Update the *CloudtraillakeEventDataStoreArn* variable in the [config.ts](config.ts) file with the ARN of the event data store you copied in step 1. Save the file. 21 | 5. Run `npm i @matthewbonig/state-machine` to install the 3rd party npm package. 22 | 6. Run `npm run build` to compile the typecript 23 | 7. Run `cdk bootstrap aws://{account-id}/{region}` with your AWS account ID and the region to which you will deploy this solution. You may need to run `npm install -g aws-cdk` if you get an error about the CDK version being outdated in your environment. 24 | 8. Run `cdk synth` to generate the Cloudformation template. 25 | 9. Run `cdk deploy` to deploy the stack 26 | 27 | After the solution is deployed, go to the [AWS Step Functions console](https://console.aws.amazon.com/states/home#/statemachines) to view the state machine and start an execution to see it in action. The sample state machine depends on having a service limit quota increase request pending or completed. 28 | 29 | ## When editing your state machine 30 | 31 | You can use this project as a base to get started building your own business logic. 32 | 1. Edit [lib/cloudtraillake-orchestrator-stack.ts](lib/cloudtraillake-orchestrator-stack.ts) with any resources you would like deployed as part of the solution. Visit this [CDK Workshop](https://cdkworkshop.com/) to learn more. 33 | 2. You can use Step Functions Workflow Studio to modify your state machine visually, and then copy the JSON definition and paste it into [step-functions/state-machine.json](step-functions/state-machine.json). 34 | 3. Then if you need any overrides added, those are defined in the *overrides* parameter of the state machine in [lib/cloudtraillake-orchestrator-stack.ts](lib/cloudtraillake-orchestrator-stack.ts) 35 | 4. After making your desired changes, save the files, and run `cdk synth` and `cdk deploy`. Optionally, you can run `cdk watch` to hot-swap deploy whenever you save a file while you are developing. 36 | 37 | ## Cloudformation deployment 38 | 39 | If you set both variables in config.py to an empty string it will read from CFN parameters instead. 40 | Grab the output from `cdk synth` to create a one-click deployment to Cloudformation. 41 | Running `cdk deploy CloudtraillakeEventDataStoreArn='full_arn_of_your_event_store' --parameters NotifyEmailAddress='your_email'` is functionality equivalent to `cdk deploy`. 42 | 43 | * Note: Deploying via Cloudformation limits your ability to incorporate your Step Functions state machine changes back into the CDK project. If you intend to adapt this solution to meet your business objectives, stick with `cdk deploy` 44 | 45 | ## Useful commands 46 | 47 | * `npm run build` compile typescript to js 48 | * `npm run watch` watch for changes and compile 49 | * `npm run test` perform the jest unit tests 50 | * `cdk deploy` deploy this stack to your default AWS account/region 51 | * `cdk diff` compare deployed stack with current state 52 | * `cdk synth` emits the synthesized CloudFormation template 53 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-child-account/template.yaml: -------------------------------------------------------------------------------- 1 | 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: Template for StackSet - Launch Lambda functions into Org. child accounts that will be triggered by SNS Topic and update SSM Document permissions 4 | Parameters: 5 | SNSTopicArn: 6 | Type: String 7 | Description: Provide an SNS Topic ARN to trigger Lambda 8 | SNSTopicRegion: 9 | Type: String 10 | Description: Enter the region the SNS Topic was created in (ex. us-east-1) 11 | Resources: 12 | LambdaGetAccountRole: 13 | Type: AWS::IAM::Role 14 | Properties: 15 | AssumeRolePolicyDocument: 16 | Statement: 17 | - Effect: Allow 18 | Action: 19 | - sts:AssumeRole 20 | Principal: 21 | Service: 22 | - lambda.amazonaws.com 23 | Version: 2012-10-17 24 | Policies: 25 | - PolicyDocument: 26 | Version: 2012-10-17 27 | Statement: 28 | - Effect: Allow 29 | Action: 30 | - ssm:ModifyDocumentPermission 31 | Resource: !Sub 'arn:aws:ssm:*:${AWS::AccountId}:document/*' 32 | - Effect: Allow 33 | Action: 34 | - ssm:ListDocuments 35 | Resource: '*' 36 | PolicyName: LambdaSSMPolicy 37 | - PolicyDocument: 38 | Version: 2012-10-17 39 | Statement: 40 | - Effect: Allow 41 | Action: 42 | - logs:CreateLogGroup 43 | Resource: '*' 44 | - Effect: Allow 45 | Action: 46 | - 'logs:CreateLogStream' 47 | - 'logs:PutLogEvents' 48 | Resource: '*' 49 | PolicyName: LambdaBasicExecPolicy 50 | 51 | LambdaInvokePermission: 52 | Type: AWS::Lambda::Permission 53 | Properties: 54 | Action: lambda:InvokeFunction 55 | Principal: sns.amazonaws.com 56 | SourceArn: !Ref SNSTopicArn 57 | FunctionName: !Ref LambdaUpdatePermissions 58 | 59 | LambdaSNSSubscription: 60 | Type: AWS::SNS::Subscription 61 | Properties: 62 | Region: !Ref SNSTopicRegion 63 | Protocol: lambda 64 | Endpoint: !GetAtt LambdaUpdatePermissions.Arn 65 | TopicArn: !Ref SNSTopicArn 66 | 67 | LambdaUpdatePermissions: 68 | Type: AWS::Lambda::Function 69 | Properties: 70 | Runtime: nodejs12.x 71 | Role: !GetAtt LambdaGetAccountRole.Arn 72 | Handler: index.handler 73 | Code: 74 | ZipFile: | 75 | var AWS = require("aws-sdk"); 76 | var ssm = new AWS.SSM(); 77 | exports.handler = function(event, context, callback) { 78 | var message = JSON.parse(event.Records[0].Sns.Message); 79 | var accountid = message.accountid.result; 80 | var type = message.type; 81 | var params = { 82 | Filters: [ 83 | { 84 | Key: 'Owner', 85 | Values: [ 86 | 'Self' 87 | ] 88 | } 89 | ] 90 | }; 91 | ssm.listDocuments(params, function(err, data) { 92 | if (err) 93 | { 94 | callback(null, err.toString()); 95 | } 96 | else 97 | { 98 | for (var i = 0; i < data.DocumentIdentifiers.length; i++) 99 | { 100 | var paramsModify = ""; 101 | if (type == "ADD") 102 | { 103 | paramsModify = { 104 | Name: data.DocumentIdentifiers[i].Name, 105 | PermissionType: 'Share', 106 | AccountIdsToAdd: [ 107 | accountid 108 | ] 109 | }; 110 | } 111 | else if (type == "REMOVE") 112 | { 113 | paramsModify = { 114 | Name: data.DocumentIdentifiers[i].Name, 115 | PermissionType: 'Share', 116 | AccountIdsToRemove: [ 117 | accountid 118 | ] 119 | }; 120 | } 121 | ssm.modifyDocumentPermission(paramsModify, function(err, data2) { 122 | if (err) 123 | { 124 | callback(null, err.toString()); // an error occurred 125 | } 126 | else 127 | { 128 | console.log(JSON.stringify(data2)); 129 | } 130 | }); 131 | } 132 | } 133 | }); 134 | }; 135 | 136 | Description: Lambda function to update SSM Document permissions with new a new AWS Account ID -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/patch-policy-examples/patch-policy-cli-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "qs-patch-policy", 3 | "Description": "Enable Patch Policy for the AWS Organization", 4 | "ConfigurationDefinitions": [{ 5 | "Type": "AWSQuickSetupType-PatchPolicy", 6 | "LocalDeploymentAdministrationRoleArn": "arn:aws:iam::123456789012:role/AWS-QuickSetup-StackSet-Local-AdministrationRole", 7 | "LocalDeploymentExecutionRoleName": "AWS-QuickSetup-StackSet-Local-ExecutionRole", 8 | "Parameters": { 9 | "ConfigurationOptionsInstallNextInterval": "true", 10 | "ConfigurationOptionsInstallValue": "cron(0 2 ? * SAT#1 *)", 11 | "ConfigurationOptionsPatchOperation": "ScanAndInstall", 12 | "ConfigurationOptionsScanNextInterval": "false", 13 | "ConfigurationOptionsScanValue": "cron(0 1 * * ? *)", 14 | "HasDeletedBaseline": "false", 15 | "IsPolicyAttachAllowed": "true", 16 | "OutputBucketRegion": "", 17 | "OutputLogEnableS3": "false", 18 | "OutputS3BucketName": "", 19 | "OutputS3KeyPrefix": "", 20 | "PatchBaselineRegion": "us-east-1", 21 | "PatchBaselineUseDefault": "custom", 22 | "PatchPolicyName": "dev-patch-policy", 23 | "RateControlConcurrency": "5", 24 | "RateControlErrorThreshold": "0%", 25 | "RebootOption": "RebootIfNeeded", 26 | "ResourceGroupName": "", 27 | "SelectedPatchBaselines": "{\"ALMA_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cb0c4966f86b059b\",\"label\":\"AWS-AlmaLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Alma Linux Provided by AWS.\",\"disabled\":false},\"AMAZON_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0c10e657807c7a700\",\"label\":\"AWS-AmazonLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Amazon Linux Provided by AWS.\",\"disabled\":false},\"AMAZON_LINUX_2\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0be8c61cde3be63f3\",\"label\":\"AWS-AmazonLinux2DefaultPatchBaseline\",\"description\":\"Baseline containing all Security and Bugfix updates approved for Amazon Linux 2 instances\",\"disabled\":false},\"AMAZON_LINUX_2022\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0028ca011460d5eaf\",\"label\":\"AWS-AmazonLinux2022DefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Amazon Linux 2022 Provided by AWS.\",\"disabled\":false},\"AMAZON_LINUX_2023\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-05c9c9bf778d4c4d0\",\"label\":\"AWS-AmazonLinux2023DefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Amazon Linux 2023 Provided by AWS.\",\"disabled\":false},\"CENTOS\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03e3f588eec25344c\",\"label\":\"AWS-CentOSDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for CentOS Provided by AWS.\",\"disabled\":false},\"DEBIAN\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-09a5f8eb62bde80b1\",\"label\":\"AWS-DebianDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Debian Provided by AWS.\",\"disabled\":false},\"MACOS\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ee4f94581368c0d4\",\"label\":\"AWS-MacOSDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for MacOS Provided by AWS.\",\"disabled\":false},\"ORACLE_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-06bff38e95fe85c02\",\"label\":\"AWS-OracleLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Oracle Linux Server Provided by AWS.\",\"disabled\":false},\"RASPBIAN\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ec16280999c5c75e\",\"label\":\"AWS-RaspbianDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Raspbian Provided by AWS.\",\"disabled\":false},\"REDHAT_ENTERPRISE_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cbb3a633de00f07c\",\"label\":\"AWS-RedHatDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Redhat Enterprise Linux Provided by AWS.\",\"disabled\":false},\"ROCKY_LINUX\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03ec98bc512aa3ac0\",\"label\":\"AWS-RockyLinuxDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Rocky Linux Provided by AWS.\",\"disabled\":false},\"SUSE\":{\"value\":\"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-07d8884178197b66b\",\"label\":\"AWS-SuseDefaultPatchBaseline\",\"description\":\"Default Patch Baseline for Suse Provided by AWS.\",\"disabled\":false},\"UBUNTU\":{\"value\":\"pb-06e3563bd35503f2b\",\"label\":\"custom-UbuntuServer-Blog-Baseline\",\"description\":\"Default Patch Baseline for Ubuntu Provided by AWS.\",\"disabled\":false},\"WINDOWS\":{\"value\":\"pb-016889927b2bb8542\",\"label\":\"custom-WindowsServer-Blog-Baseline\",\"disabled\":false}}", 28 | "TargetInstances": "", 29 | "TargetOrganizationalUnits": "ou-ab12-cdefgh34", 30 | "TargetRegions": "us-east-1,us-east-2", 31 | "TargetTagKey": "Patch", 32 | "TargetTagValue": "true", 33 | "TargetType": "Tags" 34 | } 35 | }] 36 | } -------------------------------------------------------------------------------- /AWSConfig/CloudEndureCheckReplication/README.md: -------------------------------------------------------------------------------- 1 | # CloudEndure CheckReplication Custom Rule. 2 | 3 | This sample code demonstrates how you can write and deploy an AWS Config custom rule that can be used to validate CloudEndure replication for either an ec2 instance or a on-premise server. 4 | 5 | ## Pre-requisites 6 | 7 | • AWS Config must be enabled on the region where the rule will be deployed. More information on that here. 8 | • To validate on-premise server, you must install the AWS System Manager agent on the target server and have AWS System Manager inventory enabled. For information on how to manage on-premise resources using AWS Systems Manager go here. 9 | 10 | ## How does it work? 11 | 12 | CloudEndure provides an easy-to-use API. Documentation for it can be found here. This rule uses the CloudEndure API to validate if a server is properly configured in CloudEndure. It also checks that there is no lag in replication and that the server has been tested. The Lambda function that powers the custom rule receives as a parameter 3 values: 13 | 14 | 1. The API Token needed to interact with the CloudEndure API (please note in the sample code this value is being passed as parameter. This exposes the API token in the Config Rule definition. A more robust implementation of this code should read this value from an encrypted Parameter Store Value in the code of the Lambda function.) 15 | 2. The name of the CloudEndure project where the machine should be located. 16 | 3. The EC2 instance ID, or the managed resource ID of the on-premise server, that should be validated in CloudEndure 17 | 18 | The code first determines if the resource being evaluated is an EC2 instance or an on-premise resource that has the AWS System Manager agent installed . It then queries the CloudEndure API to check if the machine exists in the configuration . It will then extract the value of the BackLoggedBytes ,the LastConsistencyDate and lastTestLaunchDateTime properties. If the value of any one of this is outside of what is expected for replication to be operational, then the resource is flagged as not compliant. The results are then returned to AWS Config. 19 | 20 | ## Overview of the sample rule 21 | 22 | ![](overview.png) 23 | 24 | ## Pre-requisites for deployment 25 | 26 | * AWS Account 27 | * AWS Administrator account or an account with enough permission to create IAM resources, Lambda functions and the AWS Config Rule 28 | * AWS Config must be enabled on the region that you will be deploying to. 29 | * An S3 bucket to state the Lambda package 30 | 31 | 32 | ## Creating the package for the lambda function. 33 | 34 | The first step is to create the Lambda function package that will be used to deploy the Lambda function for the custom rule. This function has a dependency on the requests python package which is not included in the standard Lambda image for python 2.7. To create the package follow these steps. 35 | # Download the sample code to your local computer 36 | 37 | 38 | git checkout git@ssh.gitlab.aws.dev:cca-ambassadors/cloudendurecheckreplication.git 39 | 40 | 41 | # Lets Package the python code and the dependencies to get them ready for deployment. Install the requests library so it can be packaged with the Lambda function. More info here 42 | 43 | 44 | cd lambda_function 45 | pip install requests -t ./ 46 | 47 | # the following line will create the Lambda package to be uploaded when the function is created 48 | zip -r ../CloudEndureReplicationCheck.zip . 49 | 50 | #now lets copy the package to an s3 bucket 51 | aws s3 cp CloudEndureReplicationCheck.zip s3://your-deployment-bucket/ 52 | 53 | 54 | ## Deploy the CloudFormation template 55 | 56 | The CloudFormation template creates the additional resources required to deploy the custom rule. That includes the rule, IAM role, Lambda Function. To create these resources use the AWS Console or command line . Below is an explanation of the parameters required. 57 | 58 | 59 | |Parameter |Description |Default Value| 60 | | ---------- |----------- | ------------| 61 | |Description |Description of the Config Rule |Checks replication status of a machine in Cloud Endure| 62 | |SourceBucket |Name of the S3 bucket that you have stored the rule zip files in. For example : example-bucket |See the package step and use that bucket name| 63 | |SourcePath| Path to the s3 bucket and location where you have stored the rule zip files. For example: /myrulefolder/mylambdacode.zip|| 64 | |SourceHandler |CloudEndureReplicationCheck.lambda_handler|| 65 | |SourceEvents |AWS Config resource types that will trigger the evaluation of this rule. In this case ec2 instances and SSM managed instances on-premise |AWS::EC2::Instance,AWS::SSM::ManagedInstanceInventory| 66 | |Timeout |The timeout for the Lambda function to run. |300| 67 | |RuleName |Name of the AWS Config Rule |CloudEndureCheckReplication| 68 | |LambdaFunctionName |Name of the LambdaFunction |CloudEndureCheckReplication| 69 | |SourceInputParameters |Enter the CloudEndure project name and API Token. This is for demo purposes. The API Token should be stored encrypted in a credential platform like Parameter Store or Secrets Manager|| 70 | 71 | Deploy the CloudFormation template using the Console or the CLI. Once you do you will be able to see your new AWS Config Rule . The rule will detect any resources that exist in CloudEndure and validate that they are setup properly and replicating. 72 | 73 | -------------------------------------------------------------------------------- /AWSCloudTrail/cloudtraillake-orchestrator/lib/cloudtraillake-orchestrator-stack.ts: -------------------------------------------------------------------------------- 1 | import { Duration, Stack, StackProps, CfnResource, CfnParameter } from 'aws-cdk-lib'; 2 | import { Config } from '../config'; 3 | import * as lambda from "aws-cdk-lib/aws-lambda"; 4 | import * as iam from "aws-cdk-lib/aws-iam"; 5 | import * as kms from 'aws-cdk-lib/aws-kms'; 6 | import * as sns from "aws-cdk-lib/aws-sns"; 7 | import * as subscriptions from "aws-cdk-lib/aws-sns-subscriptions"; 8 | import { Construct } from 'constructs'; 9 | import { StateMachine } from '@matthewbonig/state-machine' 10 | import * as fs from "fs"; 11 | 12 | export class CloudtraillakeOrchestratorStack extends Stack { 13 | constructor(scope: Construct, id: string, props?: StackProps) { 14 | super(scope, id, props); 15 | 16 | // Get the eventDataStore and email address from the config or from paramaters 17 | var eventDataStoreArn; 18 | if ( Config.CloudtraillakeEventDataStoreArn ) { 19 | eventDataStoreArn = Config.CloudtraillakeEventDataStoreArn 20 | } 21 | else { 22 | //console.log("CloudtraillakeEventDataStoreArn not defined in config.ts. Must be passed in as a parameter.") 23 | eventDataStoreArn = new CfnParameter(this, "CloudtraillakeEventDataStoreArn", { 24 | type: "String", 25 | allowedPattern: '^arn:aws:cloudtrail:.*', 26 | description: "The ARN of the CloudTrail Lake Event Data Store. Permission will be given to the Lambda function to query this event data store." 27 | }).valueAsString; 28 | } 29 | 30 | var emailAddress; 31 | if ( Config.NotifyEmailAddress ) { 32 | emailAddress = Config.NotifyEmailAddress; 33 | } 34 | else { 35 | emailAddress = new CfnParameter(this, "NotifyEmailAddress", { 36 | type: "String", 37 | allowedPattern: '.+\@.+', 38 | description: "The email address which will recieve notifications from SNS for any service limit quota limits that are requested. Note: you will need to check your inbox after deploying the CDK and confirm the SNS subscription" 39 | }).valueAsString; 40 | } 41 | 42 | // The Lambda function for querying the CloudTrail Lake, in Python 43 | const lambda_inline = fs.readFileSync('lambda/cloudtraillake-query.py','utf8'); 44 | const handler = new lambda.Function(this, "CloudtraillakeQueryHandler", { 45 | runtime: lambda.Runtime.PYTHON_3_9, 46 | code: lambda.Code.fromInline(lambda_inline), 47 | handler: "index.lambda_handler", 48 | timeout: Duration.minutes(5), 49 | environment: { 50 | EVENT_DATA_STORE: eventDataStoreArn 51 | } 52 | }); 53 | // give it an ID that is easier to find 54 | (handler.node.defaultChild! as CfnResource).overrideLogicalId('CloudtraillakeQuery'); 55 | 56 | // Add an IAM policy to the Lambda role to give it permission to query CloudTrail Lake event data store 57 | const statement = new iam.PolicyStatement(); 58 | statement.addActions("cloudtrail:startQuery"); 59 | statement.addActions("cloudtrail:getQueryResults"); 60 | statement.addResources(eventDataStoreArn); 61 | handler.addToRolePolicy(statement); 62 | 63 | // Create a KMS key for encrypting the SNS topic 64 | const key = new kms.Key(this, "ServiceLimitCheckerKey"); 65 | 66 | // Add an SNS topic for the Step Functions state machine to notify 67 | const topic = new sns.Topic(this, 'ServiceLimitChecker', { 68 | masterKey: key 69 | }); 70 | topic.addSubscription(new subscriptions.EmailSubscription(emailAddress)); 71 | 72 | // Create a role to for Step Functions state machine 73 | const sfRole = new iam.Role(this, 'Role', { 74 | assumedBy: new iam.ServicePrincipal('states.amazonaws.com'), 75 | description: 'Role for CloudtraillakeOrchectrator state machine to interface with other AWS resources', 76 | }); 77 | // permission to invoke cloudtrail lake query function 78 | handler.grantInvoke(sfRole); 79 | // permission to publish to the SNS topic 80 | topic.grantPublish(sfRole); 81 | // permission to encrypt via KMS to the SNS topic 82 | key.grantEncryptDecrypt(sfRole) 83 | 84 | // step functions state machine 85 | new StateMachine(this, 'CloudtraillakeOrchestrator', { 86 | role: sfRole, 87 | definition: JSON.parse(fs.readFileSync('step-functions/state-machine.json').toString()), 88 | // this is where to provide dynamic/variable overrides to the state machine definition 89 | overrides: { 90 | "CloudtraillakeQuery_RequestServiceQuotaIncrease": { 91 | "Parameters": { 92 | "FunctionName": handler.functionArn, 93 | "Payload": { 94 | "EventDataStore": "FROM_ENV" 95 | } 96 | } 97 | }, 98 | "Each_RequestServiceQuotaIncrease": { 99 | "Iterator": { 100 | "States" : { 101 | "CloudtraillakeQuery_UpdateServiceQuotaIncreaseRequestStatus": { 102 | "Parameters": { 103 | "FunctionName": handler.functionArn, 104 | "Payload": { 105 | "EventDataStore": "FROM_ENV" 106 | } 107 | } 108 | }, 109 | "Send_Report": { 110 | "Parameters": { 111 | "TopicArn": topic.topicArn 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | }); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonQOperations/SampleApp/template/AmazonQOperationSampleApp.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: 'Stack for testing Amazon Q Operational Investigation with API Gateway, Lambda, and DynamoDB' 3 | 4 | Resources: 5 | UserDataTable: 6 | Type: AWS::DynamoDB::Table 7 | Properties: 8 | TableName: UserData 9 | AttributeDefinitions: 10 | - AttributeName: userId 11 | AttributeType: S 12 | KeySchema: 13 | - AttributeName: userId 14 | KeyType: HASH 15 | BillingMode: PROVISIONED 16 | ProvisionedThroughput: 17 | ReadCapacityUnits: 5 18 | WriteCapacityUnits: 5 19 | PointInTimeRecoverySpecification: 20 | PointInTimeRecoveryEnabled: true 21 | SSESpecification: 22 | SSEEnabled: true 23 | 24 | LambdaExecutionRole: 25 | Type: AWS::IAM::Role 26 | Properties: 27 | AssumeRolePolicyDocument: 28 | Version: '2012-10-17' 29 | Statement: 30 | - Effect: Allow 31 | Principal: 32 | Service: lambda.amazonaws.com 33 | Action: sts:AssumeRole 34 | ManagedPolicyArns: 35 | - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 36 | - arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy 37 | - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess 38 | Policies: 39 | - PolicyName: DynamoDBAccess 40 | PolicyDocument: 41 | Version: '2012-10-17' 42 | Statement: 43 | - Effect: Allow 44 | Action: 45 | - dynamodb:PutItem 46 | Resource: !GetAtt UserDataTable.Arn 47 | 48 | UserDataProcessorFunction: 49 | Type: AWS::Lambda::Function 50 | Properties: 51 | FunctionName: UserDataProcessor 52 | Handler: index.lambda_handler 53 | Role: !GetAtt LambdaExecutionRole.Arn 54 | Code: 55 | ZipFile: | 56 | import json 57 | import boto3 58 | import time 59 | from botocore.exceptions import ClientError 60 | 61 | dynamodb = boto3.resource('dynamodb') 62 | table = dynamodb.Table('UserData') 63 | 64 | def lambda_handler(event, context): 65 | try: 66 | body = json.loads(event['body']) 67 | user_id = body.get('userId', str(int(time.time()))) 68 | user_data = body.get('userData', {}) 69 | 70 | response = table.put_item( 71 | Item={ 72 | 'userId': user_id, 73 | 'userData': user_data 74 | } 75 | ) 76 | return { 77 | 'statusCode': 200, 78 | 'body': json.dumps('Data stored successfully'), 79 | 'headers': { 80 | 'Content-Type': 'application/json' 81 | } 82 | } 83 | except ClientError as e: 84 | print(e.response['Error']['Message']) 85 | return { 86 | 'statusCode': 500, 87 | 'body': json.dumps('Error storing data'), 88 | 'headers': { 89 | 'Content-Type': 'application/json' 90 | } 91 | } 92 | except Exception as e: 93 | print(str(e)) 94 | return { 95 | 'statusCode': 400, 96 | 'body': json.dumps('Invalid input'), 97 | 'headers': { 98 | 'Content-Type': 'application/json' 99 | } 100 | } 101 | Runtime: python3.9 102 | Timeout: 10 103 | MemorySize: 128 104 | Environment: 105 | Variables: 106 | AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-instrument 107 | Layers: 108 | - !Sub "arn:aws:lambda:${AWS::Region}:615299751070:layer:AWSOpenTelemetryDistroPython:12" 109 | TracingConfig: 110 | Mode: Active 111 | 112 | ApiGateway: 113 | Type: AWS::ApiGateway::RestApi 114 | Properties: 115 | Name: UserDataAPI 116 | Description: API for UserData processing 117 | 118 | ApiResource: 119 | Type: AWS::ApiGateway::Resource 120 | Properties: 121 | ParentId: !GetAtt ApiGateway.RootResourceId 122 | PathPart: users 123 | RestApiId: !Ref ApiGateway 124 | 125 | ApiMethod: 126 | Type: AWS::ApiGateway::Method 127 | Properties: 128 | AuthorizationType: NONE 129 | HttpMethod: POST 130 | Integration: 131 | IntegrationHttpMethod: POST 132 | Type: AWS_PROXY 133 | Uri: !Sub 134 | - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations 135 | - LambdaArn: !GetAtt UserDataProcessorFunction.Arn 136 | ResourceId: !Ref ApiResource 137 | RestApiId: !Ref ApiGateway 138 | 139 | ApiDeployment: 140 | Type: AWS::ApiGateway::Deployment 141 | DependsOn: ApiMethod 142 | Properties: 143 | RestApiId: !Ref ApiGateway 144 | StageName: prod 145 | 146 | LambdaApiGatewayPermission: 147 | Type: AWS::Lambda::Permission 148 | Properties: 149 | Action: lambda:InvokeFunction 150 | FunctionName: !GetAtt UserDataProcessorFunction.Arn 151 | Principal: apigateway.amazonaws.com 152 | SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/POST/users 153 | 154 | Outputs: 155 | ApiUrl: 156 | Description: URL of the API endpoint 157 | Value: !Sub https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod/users 158 | 159 | -------------------------------------------------------------------------------- /AWSCloudTrail/EnableAWSCloudtrail-ExcludeKMS.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: Enable AWS CloudTrail. This template creates a CloudTrail trail, an Amazon S3 bucket where logs are published, and an Amazon SNS topic where notifications are sent. 3 | 4 | Metadata: 5 | AWS::CloudFormation::Interface: 6 | ParameterGroups: 7 | - Label: 8 | default: Trail Configuration 9 | Parameters: 10 | - EnableLogFileValidation 11 | - IncludeGlobalEvents 12 | - MultiRegion 13 | - Label: 14 | default: Delivery Notifications 15 | Parameters: 16 | - PublishToTopic 17 | - NotificationEmail 18 | ParameterLabels: 19 | EnableLogFileValidation: 20 | default: Enable log file validation 21 | IncludeGlobalEvents: 22 | default: Include global service events 23 | MultiRegion: 24 | default: Is this a multi-region trail 25 | PublishToTopic: 26 | default: Send notifications to SNS 27 | NotificationEmail: 28 | default: Notification Email (optional) 29 | 30 | Parameters: 31 | EnableLogFileValidation: 32 | Type: String 33 | Default: False 34 | Description: Indicates whether CloudTrail validates the integrity of log files. 35 | AllowedValues: 36 | - True 37 | - False 38 | 39 | IncludeGlobalEvents: 40 | Type: String 41 | Default: False 42 | Description: Indicates whether the trail is publishing events from global services, such as IAM, to the log files. 43 | AllowedValues: 44 | - True 45 | - False 46 | 47 | MultiRegion: 48 | Type: String 49 | Default: False 50 | Description: Indicates whether the CloudTrail trail is created in the region in which you create the stack (false) or in all regions (true). 51 | AllowedValues: 52 | - True 53 | - False 54 | 55 | PublishToTopic: 56 | Type: String 57 | Default: False 58 | Description: Indicates whether notifications are published to SNS. 59 | AllowedValues: 60 | - True 61 | - False 62 | 63 | NotificationEmail: 64 | Type: String 65 | Default: '' 66 | Description: Email address for notifications (for new topics). 67 | 68 | Conditions: 69 | IsMultiRegion: !Equals 70 | - !Ref MultiRegion 71 | - True 72 | Publish: !Equals 73 | - !Ref PublishToTopic 74 | - True 75 | CreateSubscription: !And 76 | - !Condition Publish 77 | - !Not 78 | - !Equals 79 | - !Ref NotificationEmail 80 | - '' 81 | 82 | Resources: 83 | TrailBucket: 84 | Type: AWS::S3::Bucket 85 | Properties: 86 | BucketEncryption: 87 | ServerSideEncryptionConfiguration: 88 | - ServerSideEncryptionByDefault: 89 | SSEAlgorithm: AES256 90 | 91 | TrailBucketPolicy: 92 | Type: AWS::S3::BucketPolicy 93 | Properties: 94 | Bucket: !Ref TrailBucket 95 | PolicyDocument: 96 | Version: 2012-10-17 97 | Statement: 98 | - Sid: AWSTrailBucketPermissionsCheck 99 | Effect: Allow 100 | Principal: 101 | Service: 102 | - cloudtrail.amazonaws.com 103 | Action: s3:GetBucketAcl 104 | Resource: 105 | - !Sub "arn:${AWS::Partition}:s3:::${TrailBucket}" 106 | - Sid: AWSTrailBucketDelivery 107 | Effect: Allow 108 | Principal: 109 | Service: 110 | - cloudtrail.amazonaws.com 111 | Action: s3:PutObject 112 | Resource: !Sub "arn:${AWS::Partition}:s3:::${TrailBucket}/AWSLogs/${AWS::AccountId}/*" 113 | - Sid: AWSTrailBucketSecureTransport 114 | Action: 115 | - s3:* 116 | Effect: Deny 117 | Resource: 118 | - !Sub "arn:${AWS::Partition}:s3:::${TrailBucket}" 119 | - !Sub "arn:${AWS::Partition}:s3:::${TrailBucket}/*" 120 | Principal: "*" 121 | Condition: 122 | Bool: 123 | aws:SecureTransport: 124 | false 125 | 126 | TrailTopic: 127 | Condition: Publish 128 | Type: AWS::SNS::Topic 129 | Properties: 130 | DisplayName: AWS CloudTrail Notification Topic 131 | KmsMasterKeyId: "alias/aws/sns" 132 | 133 | TrailTopicPolicy: 134 | Condition: Publish 135 | Type: AWS::SNS::TopicPolicy 136 | Properties: 137 | Topics: 138 | - !Ref TrailTopic 139 | PolicyDocument: 140 | Statement: 141 | - Sid: AWSCloudTrailSNSPolicy 142 | Action: 143 | - sns:Publish 144 | Effect: Allow 145 | Resource: !Ref TrailTopic 146 | Principal: 147 | Service: 148 | - cloudtrail.amazonaws.com 149 | 150 | EmailNotification: 151 | Condition: CreateSubscription 152 | Type: AWS::SNS::Subscription 153 | Properties: 154 | Endpoint: !Ref NotificationEmail 155 | Protocol: email 156 | TopicArn: !Ref TrailTopic 157 | 158 | Trail: 159 | DependsOn: 160 | - TrailBucketPolicy 161 | Type: AWS::CloudTrail::Trail 162 | Properties: 163 | S3BucketName: !Ref TrailBucket 164 | SnsTopicName: !If 165 | - Publish 166 | - !GetAtt TrailTopic.TopicName 167 | - !Ref AWS::NoValue 168 | IsLogging: true 169 | EnableLogFileValidation: !Ref EnableLogFileValidation 170 | IncludeGlobalServiceEvents: !If 171 | - IsMultiRegion 172 | - true 173 | - !Ref IncludeGlobalEvents 174 | IsMultiRegionTrail: !Ref MultiRegion 175 | EventSelectors: 176 | - DataResources: [] 177 | ReadWriteType: All 178 | IncludeManagementEvents: true 179 | ExcludeManagementEventSources: 180 | - kms.amazonaws.com 181 | 182 | -------------------------------------------------------------------------------- /AWSSystemsManager/Quick-Setup-API/patch-policy-examples/patch-policy-cfn-template.yaml: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | #------------------------------------------------------------------------------ 20 | # 21 | # Template: patch-policy-cfn-template.yaml 22 | # Purpose: CloudFormation template to deploy a Quick Setup configuration for Patch Policy. 23 | # 24 | #------------------------------------------------------------------------------ 25 | 26 | AWSTemplateFormatVersion: '2010-09-09' 27 | Description: CloudFormation template to deploy a Quick Setup configuration for Patch Policy. 28 | Resources: 29 | SSMQuickSetupTestConfigurationManager: 30 | Type: AWS::SSMQuickSetup::ConfigurationManager 31 | Properties: 32 | Name: qs-patch-policy 33 | Description: Enable Patch Policy for the AWS Organization 34 | ConfigurationDefinitions: 35 | - Type: AWSQuickSetupType-PatchPolicy 36 | LocalDeploymentAdministrationRoleArn: arn:aws:iam::682230042991:role/AWS-QuickSetup-StackSet-Local-AdministrationRole 37 | LocalDeploymentExecutionRoleName: AWS-QuickSetup-StackSet-Local-ExecutionRole 38 | Parameters: 39 | ConfigurationOptionsInstallNextInterval: 'true' 40 | ConfigurationOptionsInstallValue: cron(0 2 ? * SAT#1 *) 41 | ConfigurationOptionsPatchOperation: ScanAndInstall 42 | ConfigurationOptionsScanNextInterval: 'false' 43 | ConfigurationOptionsScanValue: cron(0 1 * * ? *) 44 | HasDeletedBaseline: 'false' 45 | IsPolicyAttachAllowed: 'true' 46 | OutputBucketRegion: '' 47 | OutputLogEnableS3: 'false' 48 | OutputS3BucketName: '' 49 | OutputS3KeyPrefix: '' 50 | PatchBaselineRegion: us-east-1 51 | PatchBaselineUseDefault: custom 52 | PatchPolicyName: dev-patch-policy 53 | RateControlConcurrency: '5' 54 | RateControlErrorThreshold: 0% 55 | RebootOption: RebootIfNeeded 56 | ResourceGroupName: '' 57 | SelectedPatchBaselines: '{"ALMA_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cb0c4966f86b059b","label":"AWS-AlmaLinuxDefaultPatchBaseline","description":"Default 58 | Patch Baseline for Alma Linux Provided by AWS.","disabled":false},"AMAZON_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0c10e657807c7a700","label":"AWS-AmazonLinuxDefaultPatchBaseline","description":"Default 59 | Patch Baseline for Amazon Linux Provided by AWS.","disabled":false},"AMAZON_LINUX_2":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0be8c61cde3be63f3","label":"AWS-AmazonLinux2DefaultPatchBaseline","description":"Baseline 60 | containing all Security and Bugfix updates approved for Amazon Linux 2 instances","disabled":false},"AMAZON_LINUX_2022":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0028ca011460d5eaf","label":"AWS-AmazonLinux2022DefaultPatchBaseline","description":"Default 61 | Patch Baseline for Amazon Linux 2022 Provided by AWS.","disabled":false},"AMAZON_LINUX_2023":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-05c9c9bf778d4c4d0","label":"AWS-AmazonLinux2023DefaultPatchBaseline","description":"Default 62 | Patch Baseline for Amazon Linux 2023 Provided by AWS.","disabled":false},"CENTOS":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03e3f588eec25344c","label":"AWS-CentOSDefaultPatchBaseline","description":"Default 63 | Patch Baseline for CentOS Provided by AWS.","disabled":false},"DEBIAN":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-09a5f8eb62bde80b1","label":"AWS-DebianDefaultPatchBaseline","description":"Default 64 | Patch Baseline for Debian Provided by AWS.","disabled":false},"MACOS":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ee4f94581368c0d4","label":"AWS-MacOSDefaultPatchBaseline","description":"Default 65 | Patch Baseline for MacOS Provided by AWS.","disabled":false},"ORACLE_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-06bff38e95fe85c02","label":"AWS-OracleLinuxDefaultPatchBaseline","description":"Default 66 | Patch Baseline for Oracle Linux Server Provided by AWS.","disabled":false},"RASPBIAN":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0ec16280999c5c75e","label":"AWS-RaspbianDefaultPatchBaseline","description":"Default 67 | Patch Baseline for Raspbian Provided by AWS.","disabled":false},"REDHAT_ENTERPRISE_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-0cbb3a633de00f07c","label":"AWS-RedHatDefaultPatchBaseline","description":"Default 68 | Patch Baseline for Redhat Enterprise Linux Provided by AWS.","disabled":false},"ROCKY_LINUX":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-03ec98bc512aa3ac0","label":"AWS-RockyLinuxDefaultPatchBaseline","description":"Default 69 | Patch Baseline for Rocky Linux Provided by AWS.","disabled":false},"SUSE":{"value":"arn:aws:ssm:us-east-1:075727635805:patchbaseline/pb-07d8884178197b66b","label":"AWS-SuseDefaultPatchBaseline","description":"Default 70 | Patch Baseline for Suse Provided by AWS.","disabled":false},"UBUNTU":{"value":"pb-06e3563bd35503f2b","label":"custom-UbuntuServer-Blog-Baseline","description":"Default 71 | Patch Baseline for Ubuntu Provided by AWS.","disabled":false},"WINDOWS":{"value":"pb-016889927b2bb8542","label":"custom-WindowsServer-Blog-Baseline","disabled":false}}' 72 | TargetInstances: '' 73 | TargetOrganizationalUnits: ou-ab12-cdefgh34 74 | TargetRegions: us-east-1,us-east-2 75 | TargetTagKey: Patch 76 | TargetTagValue: 'true' 77 | TargetType: Tags -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/README.md: -------------------------------------------------------------------------------- 1 | # AWS Config dsl Custom Rule 2 | 3 | ## This repo contains: 4 | * [Cloudformation templates](./cfn_templates/) which create: 5 | * a Lambda function for evaluating OPA policies, a Lambda layer containing the [OPA engine](https://www.openpolicyagent.org/docs/latest/), and the proper IAM permissions -> [template](./cfn_templates/lambda_backend/opa-lambda.yaml) 6 | * a custom Config rule backed by the above Lambda function, and triggered by S3 bucket changes and cheking encryption status -> [template](./cfn_templates/config_rules/opa-s3-encryption.yaml) 7 | * a custom Config rule backed by the above Lambda function, and triggered by EBS changes and cheking encryption status -> [template](./cfn_templates/config_rules/opa-ebs-encryption.yaml) 8 | * a custom Config rule backed by the above Lambda function, and triggered by EBS changes and checking attachment status -> [template](./cfn_templates/config_rules/opa-ebs-attachment.yaml) 9 | * a custom Config rule backed by the above Lambda function, and triggered by Elastic IP changes and checking attachment status -> [template](./cfn_templates/config_rules/opa-eip-attachment.yaml) 10 | 11 | 12 | * Source code for Lambda function and layers: 13 | * [Lambda function code](./lambda_sources/function/opa_lambda.py) -> `opa_lambda.py` 14 | * [Lambda function dependencies](./lambda_sources/function/lambda_requirements.txt) to be installed using `pip` -> `lambda_requirements.txt`. Currently, there are no dependencies. 15 | * [packaged assets](./lambda_sources/packaged_lambda_assets/) -> archived assets already prepared to be uploaded in S3. They contain the Lambda function. 16 | 17 | 18 | * [OPA policy files](./opa_policies/) written in [REGO](https://www.openpolicyagent.org/docs/latest/policy-language/) language, needed by the OPA engine to perform evaluations: 19 | * [opa_policy_s3_encryption](./opa_policies/opa_policy_s3_encryption.rego) evaluates an S3 bucket as `COMPLIANT` only if encryption at rest is enabled 20 | * [opa_policy_ebs_encryption](./opa_policies/opa_policy_ebs_encryption.rego) evaluates an EBS volume bucket as `COMPLIANT` only if encryption at rest is enabled 21 | 22 | 23 | * [package_lambda.sh](./package_lambda.sh) -> packages all the Lambda function and layer assets into .zip archives and places them in [packaged_lambda_assets](./lambda_sources/packaged_lambda_assets/) folder. 24 | 25 | 26 | 27 | ## Deployment Instructions 28 | 29 | * Download [OPA engine binary](https://www.openpolicyagent.org/docs/latest/#running-opa) and copy it in [aws-config-dsl-custom-rule/lambda_sources/layers/opa/bin](./lambda_sources/layers/opa/bin) 30 | 31 | * Change directory to [aws-config-dsl-custom-rule/lambda_sources/layers](./lambda_sources/layers) directory, ZIP the entire content, and COPY the zip file to [aws-config-dsl-custom-rule/lambda_sources/packaged_lambda_assets/](./lambda_sources/packaged_lambda_assets/) folder. 32 | 33 | * [**OPTIONAL**] From [aws-config-dsl-custom-rule](./) directory run `./package.sh` -> this will create the Lambda assets in the [packaged_lambda_assets](./lambda_sources/packaged_lambda_assets/) folder. **By default the assets are already in the folder and this step can be skipped if no modifications were made to the Lambda source code or Lambda layer.** 34 | 35 | 36 | * Create or use an existing S3 bucket for storing the Lambda source code and OPA policy files needed (e.g. ``) 37 | 38 | 39 | * Upload the content of [packaged_lambda_assets](./lambda_sources/packaged_lambda_assets/) into an S3 folder named `packaged_lambda_assets`: 40 | * `sources.zip` -> `/packaged_lambda_assets/sources.zip` 41 | * `opa.zip` -> `/packaged_lambda_assets/opa.zip` 42 | 43 | 44 | * Upload the content of [opa_policies](./opa_policies/) into an S3 folder named `opa_policies`: 45 | * `opa_policy_s3_encrytion.rego` -> `/opa_policies/opa_policy_s3_encrytion.rego` 46 | * `opa_policy_ebs_encrytion.rego` -> `/opa_policies/opa_policy_ebs_encrytion.rego` 47 | * `opa_policy_ebs_attachment.rego` -> `/opa_policies/opa_policy_ebs_attachment.rego` 48 | * `opa_policy_eip_attachment.rego` -> `/opa_policies/opa_policy_eip_attachment.rego` 49 | * etc... 50 | 51 | 52 | * Deploy [opa-lambda.yaml](./cfn_templates/lambda_backend/opa-lambda.yaml) using [Cloudformation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html). This will create the Lambda backend function that will evaluate your OPA policies and will be triggered by your Config rules: 53 | * use `` for the `AssetsBucket` parameter 54 | * use the default values for all the other parameters 55 | 56 | 57 | * After Lambda stack creation finished, deploy which template/s you need from the [config_rules](./cfn_templates/config_rules) folder using [Cloudformation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html). Each tempalte will create one Config rule, that will use one OPA policy and trigger the Lambda function evaluation based on AWS resource configuration change: 58 | * use `` for the `AssetsBucket` parameter 59 | * for `ConfigRuleScope` parameter use an AWS resource type, or a comma delimited list or resource types for the scope of the Config rule (e.g. `AWS::EC2::Instance, AWS::S3::Bucket`) 60 | * use the default values for all the other parameters 61 | 62 | 63 | * After the Config rule stack deployment finished, get the name of Config rule from the ouput `ConfigRuleName` and open Config service console: 64 | * Based on the [S3 encryption OPA policy](./opa_policies/opa_policy_s3_encryption.rego) we created, the [S3 encryption config Rule](./cfn_templates/config_rules/opa-s3-encryption.yaml) should find all your S3 buckets that have encryption at rest as `COMPLIANT` and the unencrypted buckets as `NON_COMPLIANT` 65 | * Based on the [EBS encryption OPA policy](./opa_policies/opa_policy_ebs_encryption.rego) we created, the [EBS encryption config Rule](./cfn_templates/config_rules/opa-ebs-encryption.yaml) should find all your EBS volumes that have encryption at rest as `COMPLIANT` and the unencrypted volumes as `NON_COMPLIANT` 66 | * Based on the [EBS attachment OPA policy](./opa_policies/opa_policy_ebs_attachment.rego) we created, the [EBS attachment config Rule](./cfn_templates/config_rules/opa-ebs-attachment.yaml) should find all your EBS volumes that are attached to an EC2 instance as `COMPLIANT` and the detached volumes as `NON_COMPLIANT` 67 | * Based on the [EIP attachment OPA policy](./opa_policies/opa_policy_eip_attachment.rego) we created, the [EIP attachment config Rule](./cfn_templates/config_rules/opa-eip-attachment.yaml) should find all your Elastic IPs that are attached to a network interface `COMPLIANT` and the detached Elastic IPs as `NON_COMPLIANT` -------------------------------------------------------------------------------- /AWSSystemsManager/ConfigurationManagement/configurationManagementExampleLambda.py: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | def lambda_handler(event, context): 20 | misconfigurations = get_keyvalue_misconfigurations(IDEAL_FILE_S3_KEY, CONFIG_SETTINGS_GROUP, CONFIG_MGMT_ATHENA_TABLE, CUSTOM_QUERIES) 21 | 22 | if misconfigurations: 23 | response = invoke_reporting_lambda(misconfigurations, context) 24 | 25 | print(response) 26 | return misconfigurations 27 | else: 28 | return [] 29 | 30 | def get_keyvalue_misconfigurations(IDEAL_FILE_S3_KEY, CONFIG_SETTINGS_GROUP, CONFIG_MGMT_ATHENA_TABLE, CUSTOM_QUERIES): 31 | 32 | aggregatedResults = [] 33 | s3Client = boto3.resource('s3') 34 | athenaClient = boto3.client('athena') 35 | 36 | # Load ideal JSON from S3 37 | idealConfig = get_ideal_config_file_from_s3(os.environ["IDEAL_FILE_S3_BUCKET"], IDEAL_FILE_S3_KEY, s3Client) 38 | 39 | # Check inventory against ideal using query builder 40 | query = compare_with_ideal_config(idealConfig, CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP) 41 | aggregatedResults += query_Athena_and_parse_response(query, athenaClient) 42 | 43 | # Check manually written queries, if any 44 | for query in CUSTOM_QUERIES: 45 | aggregatedResults += query_Athena_and_parse_response(query, athenaClient) 46 | 47 | print(aggregatedResults) 48 | 49 | return aggregatedResults 50 | 51 | 52 | def compare_with_ideal_config(idealConfig, CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP): 53 | 54 | query_list = [] 55 | aggregated_query = "" 56 | 57 | # Gets top level key, usually "common" for our use case. Use different top-level keys to 58 | # auto-build queries using a different builder function. 59 | for category in idealConfig: 60 | # Next level of keys, if statements determine whether it's a string and a structure after, or 61 | # just a string : value 62 | for key, subkey_or_value in idealConfig[category].items(): 63 | #subkey_or_value is either the subkey or value, depending on the case below 64 | if isinstance(subkey_or_value, str): 65 | #subkey_or_value is the value in this block 66 | # builds the query using the keys and values found when parsing 67 | # adds query to a list to be concatenated later 68 | query = build_query(key, None, subkey_or_value, CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP) 69 | query_list.append(query) 70 | 71 | elif isinstance(subkey_or_value, dict): 72 | #subkey_or_value is subkey in this block 73 | # json looks like string : {string, value} so this for loop parses that 74 | for subkey, value in idealConfig[category][key].items(): 75 | # same as above loop 76 | query = build_query(key, subkey, value, CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP) 77 | query_list.append(query) 78 | 79 | # need the length of the list because we can't loop through and add UNION to every query_list 80 | # because the last query in the list will not need UNION at the end 81 | list_length = len(query_list) 82 | counter = 0 83 | # concatenates queries and adds UNION in between 84 | while counter < list_length: 85 | aggregated_query += query_list[counter] 86 | if counter != list_length - 1: 87 | aggregated_query+= " UNION " 88 | counter += 1 89 | 90 | return aggregated_query 91 | 92 | def build_query(key, subkey, value, CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP): 93 | if "{condition:" in value: 94 | # 95 | elif isinstance(value, list): 96 | condition = " NOT IN " 97 | else: 98 | condition = "!=" #default conditional 99 | 100 | if "{*}" in value: #used as wildcard in ideal config file 101 | value = value.replace("{*}", "%") 102 | condition = " NOT LIKE " 103 | 104 | if subkey: 105 | if "{*}" in value: 106 | value = value.replace("{*}", "%") 107 | condition = " NOT LIKE " 108 | 109 | if "{*}" in subkey: 110 | subkey = subkey.replace("{*}", "%") 111 | subkeyCondition = " LIKE " 112 | else: 113 | subkeyCondition = "=" 114 | if subkey == '{*}': #use indicates "for any subkey, value should be..." 115 | subkey = None 116 | 117 | #append the correct query statement based on values provided 118 | if subkey is None and not isinstance(value, list): 119 | # print("entered") 120 | query = "SELECT * FROM \"paas-config-mgmt\".\"{}\" WHERE settingsgroup='{}' AND key='{}' AND value{}'{}'".format( 121 | CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP, key, condition, value 122 | ) 123 | elif subkey is None and isinstance(value, list): 124 | query = "SELECT * FROM \"paas-config-mgmt\".\"{}\" WHERE settingsgroup='{}' AND key='{}' AND value {} (".format( 125 | CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP, key, condition 126 | ) 127 | query += ', '.join(map(lambda x: "'" + x + "'", value)) + ")" 128 | elif subkey is not None and isinstance(value, list): 129 | query = "SELECT * FROM \"paas-config-mgmt\".\"{}\" WHERE settingsgroup='{}' AND key='{}' AND subkey{}'{}' AND value{} (".format( 130 | CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP, key, subkeyCondition, subkey, condition 131 | ) 132 | query += ', '.join(map(lambda x: "'" + x + "'", value)) + ")" 133 | else: 134 | query = "SELECT * FROM \"paas-config-mgmt\".\"{}\" WHERE settingsgroup='{}' AND key='{}' AND subkey{}'{}' AND value{}'{}'".format( 135 | CONFIG_MGMT_ATHENA_TABLE, CONFIG_SETTINGS_GROUP, key, subkeyCondition, subkey, condition, value 136 | ) 137 | 138 | return query 139 | -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/opsmgmt-target-account.yaml: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | #------------------------------------------------------------------------------ 20 | # 21 | # Template: opsmgmt-target-account.yaml 22 | # Purpose: Configures the target accounts for multi-account/multi-region Automation using Patch Manager 23 | # 24 | # 25 | #------------------------------------------------------------------------------ 26 | 27 | AWSTemplateFormatVersion: '2010-09-09' 28 | Description: AWS CloudFormation template to configure a target account for a scheduled multi-account and multi-region Automation patching operation. 29 | 30 | #----------------------------------------------------------- 31 | # Parameters 32 | #----------------------------------------------------------- 33 | Parameters : 34 | 35 | CentralAccountNumber : 36 | Type : 'String' 37 | Description: 'Account number for the central account.' 38 | Default: '' 39 | ExecutionLogsS3Bucket : 40 | Type : 'String' 41 | Description: 'Name of the S3 bucket that lives in the central account.' 42 | Default: '' 43 | ExecutionLogsS3BucketPrefix : 44 | Type : 'String' 45 | Description: 'Name of the prefix to use in the central account S3 bucket for inventory execution data.' 46 | Default: 'inventory-execution-logs' 47 | ExistingAutomationExecutionRole : 48 | Type : 'String' 49 | Description: '(Optional) The IAM role ARN of an Automation Execution role which has permissions to invoke patching Automation workflows and has a trust relationship with the central account.' 50 | Default: '' 51 | ManagedInstanceDataEncryptionKey: 52 | Type : 'String' 53 | Description: 'KMS Key used to encrypt S3 bucket.' 54 | Default: '' 55 | ResourceSyncS3Bucket : 56 | Type : 'String' 57 | Description: 'Name of the Resource Data Sync S3 bucket that lives in the central account.' 58 | Default: '' 59 | ResourceSyncS3BucketRegion : 60 | Type : 'String' 61 | Description: 'Region where the Resource Data Sync S3 bucket is located.' 62 | Default: '' 63 | ResourceDataSyncName : 64 | Type : 'String' 65 | Description: 'Name for the Resource Data Sync.' 66 | Default: 'InventoryData' 67 | 68 | Conditions: 69 | CreateAutomationExecutionRoleCondition: 70 | Fn::Equals: 71 | - Ref: ExistingAutomationExecutionRole 72 | - '' 73 | 74 | Resources: 75 | 76 | #------------------------------------------------- 77 | # IAM role to enable multi-account/multi-region Automation 78 | #------------------------------------------------- 79 | AutomationExecutionServiceRole: 80 | Type: AWS::IAM::Role 81 | Condition: CreateAutomationExecutionRoleCondition 82 | Properties: 83 | AssumeRolePolicyDocument: 84 | Version: '2012-10-17' 85 | Statement: 86 | - Effect: Allow 87 | Principal: 88 | Service: 89 | - ssm.amazonaws.com 90 | AWS: 91 | - !Join [ '', ['arn:aws:iam::', !Ref 'CentralAccountNumber', ':root'] ] 92 | Action: sts:AssumeRole 93 | ManagedPolicyArns: 94 | - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole 95 | Path: "/" 96 | RoleName: AWS-SystemsManager-AutomationExecutionRole 97 | Policies: 98 | - PolicyName: passRole 99 | PolicyDocument: 100 | Version: '2012-10-17' 101 | Statement: 102 | - Effect: Allow 103 | Action: 104 | - iam:PassRole 105 | Resource: 106 | - !Join [ '', ['arn:aws:iam::', !Ref 'AWS::AccountId', ':role/AWS-SystemsManager-AutomationExecutionRole'] ] 107 | - PolicyName: getTagPermissions 108 | PolicyDocument: 109 | Version: '2012-10-17' 110 | Statement: 111 | - Effect: Allow 112 | Action: 113 | - tag:GetResources 114 | Resource: "*" 115 | - PolicyName: listResourceGroupResourcesPermissions 116 | PolicyDocument: 117 | Version: '2012-10-17' 118 | Statement: 119 | - Effect: Allow 120 | Action: 121 | - resource-groups:listGroupResources 122 | Resource: "*" 123 | 124 | #------------------------------------------------- 125 | # State Manager Association to gather Inventory data using AWS-GatherSoftwareInventory 126 | #------------------------------------------------- 127 | InventoryAssociation: 128 | Type: AWS::SSM::Association 129 | Properties: 130 | AssociationName: Inventory-Association 131 | Name: AWS-GatherSoftwareInventory 132 | ScheduleExpression: "rate(1 day)" 133 | OutputLocation: 134 | S3Location: 135 | OutputS3BucketName: !Ref ExecutionLogsS3Bucket 136 | OutputS3KeyPrefix: !Join [ '', [!Ref ExecutionLogsS3BucketPrefix, '/', 'accountid=', !Ref 'AWS::AccountId', '/', 'region=', !Ref 'AWS::Region'] ] 137 | Targets: 138 | - Key: InstanceIds 139 | Values: 140 | - "*" 141 | Parameters: 142 | applications: 143 | - "Enabled" 144 | awsComponents: 145 | - "Enabled" 146 | files: 147 | - "" 148 | networkConfig: 149 | - "Enabled" 150 | windowsUpdates: 151 | - "Enabled" 152 | instanceDetailedInformation: 153 | - "Enabled" 154 | services: 155 | - "Enabled" 156 | windowsRegistry: 157 | - "" 158 | windowsRoles: 159 | - "Enabled" 160 | customInventory: 161 | - "Enabled" 162 | billingInfo: 163 | - "Enabled" 164 | 165 | #------------------------------------------------- 166 | # Resource Data Sync to aggregate inventory, patching, and compliance data in the central S3 bucket 167 | #------------------------------------------------- 168 | ResourceDataSync: 169 | Type: AWS::SSM::ResourceDataSync 170 | Properties: 171 | SyncName: !Ref ResourceDataSyncName 172 | S3Destination: 173 | BucketName: !Ref ResourceSyncS3Bucket 174 | BucketRegion: !Ref ResourceSyncS3BucketRegion 175 | KMSKeyArn: !Ref ManagedInstanceDataEncryptionKey 176 | SyncFormat: 'JsonSerDe' -------------------------------------------------------------------------------- /AWSLicenseManager/TrackLicenses_MultiRegion/LM-MULTIREGION_LicenseTracking.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: Template that creates AWS resources required to track License Consumption across multiple AWS regions in an account 3 | Parameters: 4 | LambdaTriggerSchedule: 5 | Type: String 6 | Description: Provide the schedule expression in the format of cron/rate expressions. Check https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html for more details. 7 | Default: "rate(1 day)" 8 | AllowedPattern: .+ 9 | LicenseConfigArns: 10 | Type: String 11 | Description: Provide the list of license configuration ARNs separated by comma. 12 | AllowedPattern: .+ 13 | Resources: 14 | LicenseConsumptionBucket: 15 | Type: AWS::S3::Bucket 16 | Properties: 17 | BucketName: !Sub '${AWS::AccountId}-license-consumption-reports' 18 | PublicAccessBlockConfiguration: 19 | BlockPublicAcls: true 20 | IgnorePublicAcls: true 21 | BlockPublicPolicy: true 22 | RestrictPublicBuckets: true 23 | AccessControl: Private 24 | BucketEncryption: 25 | ServerSideEncryptionConfiguration: 26 | - ServerSideEncryptionByDefault: 27 | SSEAlgorithm: AES256 28 | VersioningConfiguration: 29 | Status: Enabled 30 | LambdaRole: 31 | Type: AWS::IAM::Role 32 | Properties: 33 | AssumeRolePolicyDocument: 34 | Version: 2012-10-17 35 | Statement: 36 | - Effect: Allow 37 | Principal: 38 | Service: lambda.amazonaws.com 39 | Action: 40 | - sts:AssumeRole 41 | Path: / 42 | Policies: 43 | - PolicyName: LicenseManager-access 44 | PolicyDocument: 45 | Statement: 46 | - Effect: Allow 47 | Action: 48 | - license-manager:GetLicenseConfiguration 49 | - license-manager:ListUsageForLicenseConfiguration 50 | Resource: '*' 51 | - Effect: Allow 52 | Action: 53 | - s3:PutObject 54 | Resource: !Sub "arn:aws:s3:::${LicenseConsumptionBucket}/*" 55 | - Action: ['logs:CreateLogGroup','logs:CreateLogStream','logs:PutLogEvents'] 56 | Effect: Allow 57 | Resource: '*' 58 | LicenseTrackingLambdaFunction: 59 | Type: AWS::Lambda::Function 60 | Properties: 61 | Runtime: python3.10 62 | Role: !GetAtt LambdaRole.Arn 63 | Handler: index.handler 64 | Timeout: 120 65 | Environment: 66 | Variables: 67 | licenseConfigArns: !Ref LicenseConfigArns 68 | s3bucketName: !Ref LicenseConsumptionBucket 69 | Code: 70 | ZipFile: | 71 | import json, csv, io, os, datetime, boto3, logging, os, re 72 | # Logging setup 73 | logger = logging.getLogger() 74 | logger.setLevel(logging.INFO) 75 | 76 | def handler(event, context): 77 | try: 78 | date = datetime.datetime.now() 79 | arns = os.environ["licenseConfigArns"].split(",") 80 | logger.info(f"Provided {len(arns)} arns as input") 81 | all_arn_details = list() 82 | malformed_arns = list() 83 | # If there is arn provided, we validate the arn and fetch data for each ARN 84 | for arn in arns: 85 | # Validates if input ARN is valid 86 | p = re.compile( 87 | "arn:aws:license-manager:[a-z]{2}((-gov)|(-iso(b?)))?-[a-z]+-\d{1}:\d{12}:license-configuration:lic-+((|[a-zA-Z0-9-_]+))?") 88 | match = p.match(arn) 89 | if match: 90 | client = boto3.client('license-manager', region_name=arn.split(":")[3]) 91 | arn_details = client.get_license_configuration(LicenseConfigurationArn=arn) 92 | all_arn_details.append(arn_details) 93 | # Fetches the license usages for each one 94 | usage = client.list_usage_for_license_configuration(LicenseConfigurationArn=arn)[ 95 | "LicenseConfigurationUsageList"] 96 | if len(usage) > 0: 97 | output = io.StringIO() 98 | writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC) 99 | writer.writerow(usage[0].keys()) 100 | for use in usage: 101 | writer.writerow(use.values()) 102 | boto3.client("s3").put_object(Body=output.getvalue().encode("utf-8"), 103 | Bucket=os.environ["s3bucketName"], 104 | Key=f"{date.year}/{date.month}/{date.day}/{date}/{arn}-usage.csv") 105 | logger.info(f"Successfully stored usage information for arn {arn}") 106 | else: 107 | logger.error(f"Provided an invalid arn {arn}") 108 | malformed_arns.append(arn) 109 | logger.info(f"Generated license configurations for {len(all_arn_details)} arns") 110 | if len(all_arn_details) != 0: 111 | output = io.StringIO() 112 | writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC) 113 | writer.writerow(all_arn_details[0].keys()) 114 | for arn_detail in all_arn_details: 115 | writer.writerow(arn_detail.values()) 116 | # Upload the license details file to S3 117 | boto3.client("s3").put_object(Body=output.getvalue().encode("utf-8"), 118 | Bucket=os.environ["s3bucketName"], 119 | Key=f"{date.year}/{date.month}/{date.day}/{date}/license-consumption-summary.csv") 120 | logger.info(f"Succesfully stored all arn details") 121 | # retuns succes code on succesful run. 122 | return { 123 | 'statusCode': 200, 124 | 'body': f"Successfully uploaded license consumption details to S3, skipped {len(malformed_arns)} invalid arns" 125 | } 126 | except Exception as e: 127 | logger.error(f"Failed to fetch license configuration: {e.__repr__()}", exc_info=True) 128 | return { 129 | 'statusCode': 500, 130 | 'body': f"Unexpected exception occurred" 131 | } 132 | LicenseManagerLambdaEventRule: 133 | Type: AWS::Events::Rule 134 | Properties: 135 | Description: "Schedule rule to trigger lambda to fetch license usage" 136 | Name: "LicenseManagerLambdaEventJob" 137 | ScheduleExpression: !Ref LambdaTriggerSchedule 138 | State: ENABLED 139 | Targets: 140 | - 141 | Arn: !GetAtt LicenseTrackingLambdaFunction.Arn 142 | Id: "LicenseTrackingLambdaFunction" 143 | -------------------------------------------------------------------------------- /AWSConfig/AWS-Config-OPA/lambda_sources/function/opa_lambda.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import boto3 4 | import logging 5 | from botocore.exceptions import ClientError 6 | import subprocess 7 | import tempfile 8 | 9 | 10 | logging_level = os.environ['LOGGING_LEVEL'] 11 | 12 | logger = logging.getLogger(__name__) 13 | logger.setLevel(logging_level) 14 | handler = logging.StreamHandler() 15 | logger.addHandler(handler) 16 | formatter = logging.Formatter( 17 | '[%(asctime)s] %(levelname)s @ line %(lineno)d: %(message)s') 18 | handler.setFormatter(formatter) 19 | logger.propagate = False 20 | 21 | 22 | class Opa(object): 23 | def __init__(self, input_file_name, policy_package_name, rule_to_eval) -> None: 24 | try: 25 | self.input_file_path = input_file_name 26 | self.query = '"data.{}.{}"'.format(policy_package_name, 27 | rule_to_eval) 28 | except Exception as e: 29 | logger.error(e) 30 | raise 31 | else: 32 | logger.info('OPA input query: {}'.format(self.query)) 33 | 34 | def eval_compliance(self, policy_file_path) -> bool: 35 | try: 36 | command = 'opa eval -d {} -i {} {}'.format(policy_file_path, 37 | self.input_file_path, 38 | self.query) 39 | logger.debug('OPA eval command: {}'.format(command)) 40 | output = run_process(command) 41 | for result in output['result']: 42 | for _ in result['expressions']: 43 | logger.debug('OPA output query: {}'.format(_['text'])) 44 | if '"{}"'.format(_['text']) == self.query: 45 | compliance = _['value'] 46 | logger.debug( 47 | 'OPA output compliance: {}'.format(compliance) 48 | ) 49 | logger.info('OPA compliance evaluated successfully') 50 | return compliance 51 | except Exception as e: 52 | logger.error(e) 53 | raise 54 | 55 | 56 | class Config(object): 57 | def __init__(self, event) -> None: 58 | self.config_event = json.loads(event['invokingEvent']) 59 | self.config_item = self.config_event['configurationItem'] 60 | logger.debug('Config Item: {}'.format(self.config_item)) 61 | self.result_token = event['resultToken'] 62 | logger.debug('Result token: {}'.format(self.result_token)) 63 | self.input_parameters = json.loads(event['ruleParameters']) 64 | logger.debug('Config rule parameters: {}'.format(self.input_parameters)) 65 | self.message_type = self.config_event['messageType'] 66 | logger.debug('Config message type: {}'.format(self.message_type)) 67 | self.resource_id = self.config_item['resourceId'] 68 | logger.debug('AWS resource id: {}'.format(self.resource_id)) 69 | self.resource_status = self.config_item['configurationItemStatus'] 70 | logger.debug('AWS resource status: {}'.format(self.resource_status)) 71 | self.client = boto3.client('config') 72 | 73 | def set_compliance(self, compliance) -> None: 74 | evaluation = { 75 | 'Annotation': 'Setting compliance based on OPA policy evaluation.\n', 76 | 'ComplianceResourceType': self.config_item['resourceType'], 77 | 'ComplianceResourceId': self.config_item['resourceId'], 78 | 'OrderingTimestamp': self.config_item['configurationItemCaptureTime'] 79 | } 80 | if self.resource_status == 'ResourceDeleted': 81 | evaluation['ComplianceType'] = 'NOT_APPLICABLE' 82 | msg = 'Resource {} is deleted, setting Compliance Status to ' \ 83 | 'NOT_APPLICABLE.'.format(self.resource_id) 84 | logger.info(msg) 85 | evaluation['Annotation'] += msg 86 | elif compliance: 87 | evaluation['ComplianceType'] = 'COMPLIANT' 88 | msg = 'Resource {} is compliant'.format(self.resource_id) 89 | logger.info(msg) 90 | evaluation['Annotation'] += msg 91 | else: 92 | evaluation['ComplianceType'] = 'NON_COMPLIANT' 93 | msg = 'Resource {} is NOT compliant'.format(self.resource_id) 94 | logger.info(msg) 95 | evaluation['Annotation'] += msg 96 | try: 97 | self.client.put_evaluations(Evaluations=[evaluation], 98 | ResultToken=self.result_token) 99 | except ClientError as e: 100 | logger.error( 101 | 'Config service PUT Evaluation failed with error: {}'.format( 102 | e.response['Error']['Message'] 103 | ) 104 | ) 105 | 106 | 107 | def download_s3_obj(bucket, prefix, object_key) -> str: 108 | try: 109 | s3 = boto3.resource('s3') 110 | object_path = ''.join([prefix, object_key]) 111 | obj = s3.Object(bucket, object_path) 112 | obj_body = obj.get()['Body'].read().decode('utf-8') 113 | except ClientError as e: 114 | logger.error('S3 download file failed with: {}'.format( 115 | e.response['Error']['Message'])) 116 | except Exception as e: 117 | logger.error(e) 118 | else: 119 | return obj_body 120 | 121 | 122 | def run_process(command): 123 | try: 124 | process = subprocess.run( 125 | command, 126 | capture_output=True, 127 | shell=True, 128 | encoding='utf-8' 129 | ) 130 | except BrokenPipeError as e: 131 | logger.error('Process failed with {}'.format(e)) 132 | raise 133 | except Exception as e: 134 | logger.error('Process failed with {}'.format(e)) 135 | raise 136 | else: 137 | output = json.loads(process.stdout) 138 | logger.debug('Shell command stdout: {}'.format(output)) 139 | return output 140 | 141 | 142 | def get_tempfile(content): 143 | try: 144 | tf = tempfile.NamedTemporaryFile(mode='w+', encoding='utf-8') 145 | tf.write(content) 146 | tf.seek(0) 147 | except Exception as e: 148 | logger.error('Creating tempfile failed with {}'.format(e)) 149 | raise 150 | else: 151 | return tf 152 | 153 | 154 | def lambda_handler(event, context): 155 | try: 156 | logger.debug('Lambda event: {}'.format(event)) 157 | config = Config(event) 158 | logger.info('Config input processed') 159 | 160 | input_file = get_tempfile(json.dumps(config.config_item)) 161 | logger.info('OPA input file created') 162 | logger.debug('Name of the input file is: {}'.format(input_file.name)) 163 | 164 | policy_file = get_tempfile(download_s3_obj( 165 | config.input_parameters['ASSETS_BUCKET'], 166 | config.input_parameters['REGO_POLICIES_PREFIX'], 167 | config.input_parameters['REGO_POLICY_KEY'] 168 | )) 169 | logger.info('OPA policy file created') 170 | logger.debug('Name of the policy file is: {}'.format(policy_file.name)) 171 | 172 | opa = Opa( 173 | input_file.name, 174 | config.input_parameters['OPA_POLICY_PACKAGE_NAME'], 175 | config.input_parameters['OPA_POLICY_RULE_TO_EVAL'] 176 | ) 177 | 178 | config.set_compliance(opa.eval_compliance(policy_file.name)) 179 | finally: 180 | try: 181 | input_file.close() 182 | policy_file.close() 183 | except UnboundLocalError as e: 184 | logger.error( 185 | 'Tempfiles not created. Nothing to close. Error: {}'.format(e) 186 | ) 187 | else: 188 | logger.info("Temp files have been closed") 189 | -------------------------------------------------------------------------------- /AWSSystemsManager/AWS-Org-SSM-Permissions/ssm-management-account/README.md: -------------------------------------------------------------------------------- 1 | # ssm-management-account 2 | 3 | This project directory contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders: 4 | 5 | - * **getaccountid** - Lambda function to retrieve new AWS Organizations account 6 | - * **invitationtest** - Lambda function to test an event against AWS Organizations InviteAccountToOrganization API call 7 | - * **publishaccountid** - Lambda function to fan out the new account id via SNS to subscribing child accounts 8 | - * **template.yaml** - A template that defines the application's AWS resources. 9 | 10 | The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. 11 | 12 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit. 13 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started. 14 | 15 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 16 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) 17 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) 18 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html) 19 | 20 | ## Deploy the sample application 21 | 22 | The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. 23 | 24 | To use the SAM CLI, you need the following tools. 25 | 26 | * SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) 27 | * Node.js - [Install Node.js 10](https://nodejs.org/en/), including the NPM package management tool. 28 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) 29 | 30 | To build and deploy your application for the first time, run the following in your shell: 31 | 32 | ```bash 33 | sam build 34 | sam deploy --guided 35 | ``` 36 | 37 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: 38 | 39 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. 40 | * **AWS Region**: The region to deploy your resources. 41 | * **AccountTwoID**: Parameter for the 12-digit AWS Organizations child account (XXXXXXXXXXXX) that contains your SSM Documents 42 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. 43 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. 44 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. 45 | 46 | You can find your API Gateway Endpoint URL in the output values displayed after deployment. 47 | 48 | ## Use the SAM CLI to build and test locally 49 | 50 | Build your application with the `sam build` command. 51 | 52 | ```bash 53 | ssm-account-share$ sam build 54 | ``` 55 | 56 | The SAM CLI installs dependencies defined in `hello-world/package.json`, creates a deployment package, and saves it in the `.aws-sam/build` folder. 57 | 58 | Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. 59 | 60 | Run functions locally and invoke them with the `sam local invoke` command. 61 | 62 | ```bash 63 | ssm-account-share$ sam local invoke HelloWorldFunction --event events/event.json 64 | ``` 65 | 66 | The SAM CLI can also emulate your application's API. Use the `sam local start-api` to run the API locally on port 3000. 67 | 68 | ```bash 69 | ssm-account-share$ sam local start-api 70 | ssm-account-share$ curl http://localhost:3000/ 71 | ``` 72 | 73 | The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The `Events` property on each function's definition includes the route and method for each path. 74 | 75 | ```yaml 76 | Events: 77 | HelloWorld: 78 | Type: Api 79 | Properties: 80 | Path: /hello 81 | Method: get 82 | ``` 83 | 84 | ## Add a resource to your application 85 | The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in [the SAM specification](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md), you can use standard [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) resource types. 86 | 87 | ## Fetch, tail, and filter Lambda function logs 88 | 89 | To simplify troubleshooting, SAM CLI has a command called `sam logs`. `sam logs` lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug. 90 | 91 | `NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM. 92 | 93 | ```bash 94 | ssm-account-share$ sam logs -n HelloWorldFunction --stack-name ssm-account-share --tail 95 | ``` 96 | 97 | You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html). 98 | 99 | ## Cleanup 100 | 101 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following: 102 | 103 | ```bash 104 | aws cloudformation delete-stack --stack-name ssm-account-share 105 | ``` 106 | 107 | ## Resources 108 | 109 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to SAM specification, the SAM CLI, and serverless application concepts. 110 | 111 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/) 112 | -------------------------------------------------------------------------------- /AWSConfig/ConformancePacks/CP-IAMBestPractices.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: This template automatically deploy the AWS Config Conformance Pack for Operational Best Practices for AWS Identity And Access Management. Please note resource charges for S3 buckets, Config and Conformance pack will apply. 3 | Parameters: 4 | ConformancePackDeliveryBucket: 5 | Type: String 6 | Description: AWS Config stores intermediate files while processing conformance pack template. Please enter thename of the bucket that has been configured already for conformance pack to deliver to deliver findings. 7 | MaxAgeAccessKeyRotated: 8 | Type: String 9 | Description: This is a parameter for the conformance pack. Enter the IAM Access Key Maximum number of days without rotation. Default 90 10 | Default: '90' 11 | BlackListedIAMPolicyARN: 12 | Type: String 13 | Default: 'arn:aws:iam::aws:policy/PowerUserAccess' 14 | Description: >- 15 | This is a parameter for the conformance pack. Enter a Comma-separated list of IAM policy ARNs that should not be attached to any 16 | IAM entity. We provide as the PowerUserAccess for sample purposes only. Feel free to enter asnother policy ARN 17 | IAMUserUnusedCredentialAge: 18 | Type: String 19 | Description: >- 20 | This is a parameter for the conformance pack. Maximum number of days a credential cannot be used. The default value is 21 | 90 days. 22 | Default: '90' 23 | Resources: 24 | ConformancePack: 25 | Type: 'AWS::Config::ConformancePack' 26 | Properties: 27 | ConformancePackName: IAMBestPractices 28 | ConformancePackInputParameters: 29 | - 30 | ParameterName: AccessKeysRotatedParameterMaxAccessKeyAge 31 | ParameterValue: !Ref MaxAgeAccessKeyRotated 32 | - 33 | ParameterName: IAMPolicyBlacklistedCheckParameterPolicyArns 34 | ParameterValue: !Ref BlackListedIAMPolicyARN 35 | - 36 | ParameterName: IAMUserUnusedCredentialsCheckParameterMaxCredentialUsageAge 37 | ParameterValue: !Ref IAMUserUnusedCredentialAge 38 | DeliveryS3Bucket: !Ref ConformancePackDeliveryBucket 39 | TemplateBody: |- 40 | Parameters: 41 | AccessKeysRotatedParameterMaxAccessKeyAge: 42 | Description: Maximum number of days without rotation. Default 90. 43 | Type: String 44 | IAMPolicyBlacklistedCheckParameterPolicyArns: 45 | Description: Comma-separated list of IAM policy ARNs that should not be attached to any IAM entity. 46 | Type: String 47 | IAMUserUnusedCredentialsCheckParameterMaxCredentialUsageAge: 48 | Description: Maximum number of days a credential cannot be used. The default value 49 | is 90 days. 50 | Type: String 51 | Resources: 52 | AccessKeysRotated: 53 | Properties: 54 | ConfigRuleName: AccessKeysRotated 55 | Description: Checks whether the active access keys are rotated within the number 56 | of days specified in maxAccessKeyAge. The rule is non-compliant if the access 57 | keys have not been rotated for more than maxAccessKeyAge number of days. 58 | InputParameters: 59 | maxAccessKeyAge: 60 | Ref: AccessKeysRotatedParameterMaxAccessKeyAge 61 | Source: 62 | Owner: AWS 63 | SourceIdentifier: ACCESS_KEYS_ROTATED 64 | Type: AWS::Config::ConfigRule 65 | IAMGroupHasUsersCheck: 66 | Properties: 67 | ConfigRuleName: IAMGroupHasUsersCheck 68 | Description: Checks whether IAM groups have at least one IAM user. 69 | Source: 70 | Owner: AWS 71 | SourceIdentifier: IAM_GROUP_HAS_USERS_CHECK 72 | Type: AWS::Config::ConfigRule 73 | IAMPasswordPolicy: 74 | Properties: 75 | ConfigRuleName: IAMPasswordPolicy 76 | Description: Checks whether the account password policy for IAM users meets 77 | the specified requirements. 78 | Source: 79 | Owner: AWS 80 | SourceIdentifier: IAM_PASSWORD_POLICY 81 | Type: AWS::Config::ConfigRule 82 | IAMPolicyBlacklistedCheck: 83 | Properties: 84 | ConfigRuleName: IAMPolicyBlacklistedCheck 85 | Description: Checks that none of your IAM users, groups, or roles (excluding 86 | exceptionList) have the specified policies attached. 87 | InputParameters: 88 | policyArns: 89 | Ref: IAMPolicyBlacklistedCheckParameterPolicyArns 90 | Source: 91 | Owner: AWS 92 | SourceIdentifier: IAM_POLICY_BLACKLISTED_CHECK 93 | Type: AWS::Config::ConfigRule 94 | IAMPolicyNoStatementsWithAdminAccess: 95 | Properties: 96 | ConfigRuleName: IAMPolicyNoStatementsWithAdminAccess 97 | Source: 98 | Owner: AWS 99 | SourceIdentifier: IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS 100 | Type: AWS::Config::ConfigRule 101 | IAMRootAccessKeyCheck: 102 | Properties: 103 | ConfigRuleName: IAMRootAccessKeyCheck 104 | Description: Checks whether the root user access key is available. The rule 105 | is compliant if the user access key does not exist. 106 | Source: 107 | Owner: AWS 108 | SourceIdentifier: IAM_ROOT_ACCESS_KEY_CHECK 109 | Type: AWS::Config::ConfigRule 110 | IAMUserGroupMembershipCheck: 111 | Properties: 112 | ConfigRuleName: IAMUserGroupMembershipCheck 113 | Description: Checks whether IAM users are members of at least one IAM group. 114 | Source: 115 | Owner: AWS 116 | SourceIdentifier: IAM_USER_GROUP_MEMBERSHIP_CHECK 117 | Type: AWS::Config::ConfigRule 118 | IAMUserMFAEnabled: 119 | Properties: 120 | ConfigRuleName: IAMUserMFAEnabled 121 | Description: Checks whether the AWS Identity and Access Management users have 122 | multi-factor authentication (MFA) enabled. 123 | Source: 124 | Owner: AWS 125 | SourceIdentifier: IAM_USER_MFA_ENABLED 126 | Type: AWS::Config::ConfigRule 127 | IAMUserNoPoliciesCheck: 128 | Properties: 129 | ConfigRuleName: IAMUserNoPoliciesCheck 130 | Description: Checks that none of your IAM users have policies attached. IAM 131 | users must inherit permissions from IAM groups or roles. 132 | Source: 133 | Owner: AWS 134 | SourceIdentifier: IAM_USER_NO_POLICIES_CHECK 135 | Type: AWS::Config::ConfigRule 136 | IAMUserUnusedCredentialsCheck: 137 | Properties: 138 | ConfigRuleName: IAMUserUnusedCredentialsCheck 139 | Description: Checks whether your AWS Identity and Access Management (IAM) users 140 | have passwords or active access keys that have not been used within the specified 141 | number of days you provided. 142 | InputParameters: 143 | maxCredentialUsageAge: 144 | Ref: IAMUserUnusedCredentialsCheckParameterMaxCredentialUsageAge 145 | Source: 146 | Owner: AWS 147 | SourceIdentifier: IAM_USER_UNUSED_CREDENTIALS_CHECK 148 | Type: AWS::Config::ConfigRule 149 | MFAEnabledForIAMConsoleAccess: 150 | Properties: 151 | ConfigRuleName: MFAEnabledForIAMConsoleAccess 152 | Description: Checks whether AWS Multi-Factor Authentication (MFA) is enabled 153 | for all AWS Identity and Access Management (IAM) users that use a console 154 | password. The rule is compliant if MFA is enabled. 155 | Source: 156 | Owner: AWS 157 | SourceIdentifier: MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS 158 | Type: AWS::Config::ConfigRule 159 | RootAccountHardwareMFAEnabled: 160 | Properties: 161 | ConfigRuleName: RootAccountHardwareMFAEnabled 162 | Description: Checks whether your AWS account is enabled to use a multi-factor 163 | authentication (MFA) hardware device to sign in with root credentials. 164 | Source: 165 | Owner: AWS 166 | SourceIdentifier: ROOT_ACCOUNT_HARDWARE_MFA_ENABLED 167 | Type: AWS::Config::ConfigRule 168 | RootAccountMFAEnabled: 169 | Properties: 170 | ConfigRuleName: RootAccountMFAEnabled 171 | Description: Checks whether the root user of your AWS account requires multi-factor 172 | authentication for console sign-in. 173 | Source: 174 | Owner: AWS 175 | SourceIdentifier: ROOT_ACCOUNT_MFA_ENABLED 176 | Type: AWS::Config::ConfigRule 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /AmazonObservability/AmazonQOperations/Canary/SyntheticsCanary.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: 'CloudFormation template for CloudWatch Synthetics Canary with increased load' 3 | 4 | Parameters: 5 | ApiEndpoint: 6 | Type: String 7 | Description: 'The API endpoint URL to test' 8 | 9 | CanaryRuntimeVersion: 10 | Type: String 11 | Description: 'Runtime version for the canary. See here for more information https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html' 12 | Default: 'syn-nodejs-puppeteer-9.1' 13 | 14 | CanaryFrequency: 15 | Type: String 16 | Description: 'Frequency of canary runs (in minutes)' 17 | Default: '5' 18 | AllowedValues: ['1', '5', '10', '15', '30', '60'] 19 | 20 | RequestsPerRun: 21 | Type: Number 22 | Description: 'Number of requests to send per canary run' 23 | Default: 10 24 | MinValue: 1 25 | MaxValue: 100 26 | 27 | Resources: 28 | CanaryArtifactsBucket: 29 | Type: 'AWS::S3::Bucket' 30 | Properties: 31 | BucketName: !Join 32 | - '-' 33 | - - 'canary-artifacts' 34 | - !Select [2, !Split ["/", !Ref AWS::StackId]] 35 | LifecycleConfiguration: 36 | Rules: 37 | - Id: DeleteOldArtifacts 38 | Status: Enabled 39 | ExpirationInDays: 30 40 | BucketEncryption: 41 | ServerSideEncryptionConfiguration: 42 | - ServerSideEncryptionByDefault: 43 | SSEAlgorithm: 'AES256' 44 | PublicAccessBlockConfiguration: 45 | IgnorePublicAcls: true 46 | ObjectLockEnabled: true 47 | VersioningConfiguration: 48 | Status: Enabled 49 | 50 | CanaryArtifactsBucketPolicy: 51 | Type: AWS::S3::BucketPolicy 52 | Properties: 53 | Bucket: !Ref CanaryArtifactsBucket 54 | PolicyDocument: 55 | Version: '2012-10-17' 56 | Statement: 57 | - Sid: AllowCanaryPutObjects 58 | Effect: Allow 59 | Principal: 60 | AWS: !GetAtt SyntheticsCanaryRole.Arn 61 | Action: 62 | - s3:PutObject 63 | - s3:GetObject 64 | - s3:ListBucket 65 | Resource: 66 | - !Sub 'arn:aws:s3:::${CanaryArtifactsBucket}' 67 | - !Sub 'arn:aws:s3:::${CanaryArtifactsBucket}/*' 68 | 69 | SyntheticsCanaryRole: 70 | Type: AWS::IAM::Role 71 | Properties: 72 | AssumeRolePolicyDocument: 73 | Version: '2012-10-17' 74 | Statement: 75 | - Effect: Allow 76 | Principal: 77 | Service: lambda.amazonaws.com 78 | Action: sts:AssumeRole 79 | ManagedPolicyArns: 80 | - arn:aws:iam::aws:policy/CloudWatchSyntheticsFullAccess 81 | - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 82 | Policies: 83 | - PolicyName: S3BucketAccess 84 | PolicyDocument: 85 | Version: '2012-10-17' 86 | Statement: 87 | - Effect: Allow 88 | Action: 89 | - s3:PutObject 90 | - s3:GetObject 91 | - s3:ListBucket 92 | Resource: 93 | - !Sub 'arn:aws:s3:::${CanaryArtifactsBucket}' 94 | - !Sub 'arn:aws:s3:::${CanaryArtifactsBucket}/*' 95 | 96 | 97 | SyntheticsCanary: 98 | Type: AWS::Synthetics::Canary 99 | Properties: 100 | Name: !Sub '${AWS::StackName}-load-test-canary' 101 | ArtifactS3Location: !Sub 's3://${CanaryArtifactsBucket}/${AWS::StackName}' 102 | ExecutionRoleArn: !GetAtt SyntheticsCanaryRole.Arn 103 | RuntimeVersion: 'syn-nodejs-puppeteer-9.1' 104 | Schedule: 105 | Expression: !Sub 'rate(${CanaryFrequency} minutes)' 106 | StartCanaryAfterCreation: true 107 | RunConfig: 108 | TimeoutInSeconds: 300 109 | EnvironmentVariables: 110 | API_ENDPOINT: !Ref ApiEndpoint 111 | REQUESTS_PER_RUN: !Ref RequestsPerRun 112 | PAYLOAD_SIZE_KB: '256' 113 | Code: 114 | Handler: index.handler 115 | Script: | 116 | const synthetics = require('Synthetics'); 117 | const https = require('https'); 118 | const log = require('SyntheticsLogger'); 119 | 120 | const apiEndpoint = process.env.API_ENDPOINT; 121 | const requestsPerRun = parseInt(process.env.REQUESTS_PER_RUN, 10); 122 | const payloadSizeKB = parseInt(process.env.PAYLOAD_SIZE_KB, 10); 123 | 124 | // Generate large random data 125 | const generateLargePayload = (sizeInKB) => { 126 | const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 127 | const iterations = (sizeInKB * 1024) / characters.length; 128 | let result = ''; 129 | 130 | for (let i = 0; i < iterations; i++) { 131 | result += characters; 132 | } 133 | return result; 134 | }; 135 | 136 | const makeRequest = async (method, data = null) => { 137 | const requestOptions = { 138 | hostname: new URL(apiEndpoint).hostname, 139 | port: 443, 140 | path: new URL(apiEndpoint).pathname, 141 | method: method, 142 | headers: { 143 | 'Content-Type': 'application/json' 144 | } 145 | }; 146 | 147 | if (data) { 148 | const postBody = JSON.stringify(data); 149 | requestOptions.headers['Content-Length'] = Buffer.byteLength(postBody); 150 | } 151 | 152 | return new Promise((resolve, reject) => { 153 | const req = https.request(requestOptions, (res) => { 154 | let responseBody = ''; 155 | res.on('data', (chunk) => { 156 | responseBody += chunk; 157 | }); 158 | 159 | res.on('end', () => { 160 | if (res.statusCode >= 200 && res.statusCode < 300) { 161 | resolve({ 162 | statusCode: res.statusCode, 163 | body: responseBody 164 | }); 165 | } else { 166 | reject(new Error(`HTTP Error: ${res.statusCode}`)); 167 | } 168 | }); 169 | }); 170 | 171 | req.on('error', reject); 172 | 173 | if (data) { 174 | req.write(JSON.stringify(data)); 175 | } 176 | req.end(); 177 | }); 178 | }; 179 | 180 | const handler = async () => { 181 | const operations = []; 182 | 183 | for (let i = 0; i < requestsPerRun; i++) { 184 | const userId = `user_${Date.now()}_${Math.random().toString(36).substring(7)}`; 185 | const data = { 186 | userId: userId, 187 | timestamp: Date.now(), 188 | payload: generateLargePayload(payloadSizeKB), 189 | metadata: { 190 | iteration: i, 191 | random: Math.random(), 192 | nested: { 193 | field1: Math.random().toString(36), 194 | field2: Math.random().toString(36), 195 | field3: Array.from({length: 10}, () => Math.random()) 196 | } 197 | } 198 | }; 199 | 200 | operations.push( 201 | makeRequest('POST', data) 202 | .then(result => ({type: 'write', success: true, result})) 203 | .catch(error => ({type: 'write', success: false, error: error.message})) 204 | ); 205 | } 206 | 207 | try { 208 | const results = await Promise.all(operations); 209 | const summary = results.reduce((acc, result) => { 210 | const key = `${result.type}${result.success ? 'Success' : 'Failed'}`; 211 | acc[key] = (acc[key] || 0) + 1; 212 | return acc; 213 | }, {}); 214 | 215 | log.info('Load Test Summary:', summary); 216 | 217 | const failures = results.filter(r => !r.success); 218 | if (failures.length > 0) { 219 | throw new Error(`Load test had ${failures.length} failures`); 220 | } 221 | } catch (error) { 222 | log.error('Load test failed:', error); 223 | throw error; 224 | } 225 | }; 226 | 227 | exports.handler = async () => { 228 | return await handler(); 229 | }; 230 | 231 | 232 | 233 | Outputs: 234 | CanaryName: 235 | Description: 'Name of the created CloudWatch Synthetics Canary' 236 | Value: !Ref SyntheticsCanary 237 | -------------------------------------------------------------------------------- /AWSSystemsManager/CentralizedPatchManagement/opsmgmt-deploy-test-instances.yaml: -------------------------------------------------------------------------------- 1 | #* 2 | #* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | #* SPDX-License-Identifier: MIT-0 4 | #* 5 | #* Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | #* software and associated documentation files (the "Software"), to deal in the Software 7 | #* without restriction, including without limitation the rights to use, copy, modify, 8 | #* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | #* permit persons to whom the Software is furnished to do so. 10 | #* 11 | #* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | #* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | #* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | #* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | #* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | #* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | #* 18 | 19 | #------------------------------------------------------------------------------ 20 | # 21 | # Template: opsmgmt-deploy-test-instances.yaml 22 | # Purpose: CloudFormation template to deploy test instances for patching using multi-account/multi-Region Automation 23 | # 24 | # 25 | #------------------------------------------------------------------------------ 26 | 27 | AWSTemplateFormatVersion: '2010-09-09' 28 | Description: AWS CloudFormation template to launch instances for Inventory, Patching, and Compliance demo environment for AWS Systems Manager 29 | 30 | #----------------------------------------------------------- 31 | # Parameters 32 | #----------------------------------------------------------- 33 | Parameters : 34 | ExecutionLogsS3Bucket : 35 | Type : 'String' 36 | Description: 'Name of the execution logs S3 bucket that lives in the central account.' 37 | ExistingManagedInstanceProfile : 38 | Type : 'String' 39 | Description : "(Optional) The name of the IAM Instance Profile that grants permissions to AWS Systems Manager." 40 | Default: '' 41 | LatestWindowsAmiId : 42 | # Use public Systems Manager Parameter 43 | Type : 'AWS::SSM::Parameter::Value' 44 | Default: '/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base' 45 | LatestAmazonLinuxAmiId : 46 | # Use public Systems Manager Parameter 47 | Type : 'AWS::SSM::Parameter::Value' 48 | Default: '/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2' 49 | 50 | Conditions: 51 | CreateManagedInstanceProfileCondition: 52 | Fn::Equals: 53 | - Ref: ExistingManagedInstanceProfile 54 | - '' 55 | 56 | Resources: 57 | 58 | #------------------------------------------------- 59 | # Resource Group to target for multi-account/multi-Region Automation 60 | #------------------------------------------------- 61 | WebServersRG: 62 | Type: AWS::ResourceGroups::Group 63 | Properties: 64 | Description: 'This is a test Resource Group' 65 | Name: WebServers 66 | ResourceQuery: 67 | Type: "TAG_FILTERS_1_0" 68 | Query: 69 | ResourceTypeFilters: 70 | - "AWS::AllSupported" 71 | TagFilters: 72 | - 73 | Key: "Patch" 74 | Values: 75 | - "True" 76 | 77 | #------------------------------------------------- 78 | # IAM role and instance profile to enable Systems Manager registration on EC2 instances 79 | #------------------------------------------------- 80 | ManagedInstanceRole: 81 | Type: AWS::IAM::Role 82 | Condition: CreateManagedInstanceProfileCondition 83 | Properties: 84 | AssumeRolePolicyDocument: 85 | Version: '2012-10-17' 86 | Statement: 87 | - Effect: Allow 88 | Principal: 89 | Service: 90 | - ec2.amazonaws.com 91 | Action: sts:AssumeRole 92 | ManagedPolicyArns: 93 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 94 | Path: "/" 95 | Policies: 96 | - PolicyName: CentralAccountS3Permissions 97 | PolicyDocument: 98 | Version: '2012-10-17' 99 | Statement: 100 | - Effect: Allow 101 | Action: 102 | - s3:GetObject 103 | - s3:PutObject 104 | - s3:PutObjectAcl 105 | Resource: 106 | - !Join [ '', ['arn:aws:s3:::', !Ref 'ExecutionLogsS3Bucket'] ] 107 | - !Join [ '', ['arn:aws:s3:::', !Ref 'ExecutionLogsS3Bucket', '/*'] ] 108 | ManagedInstanceProfile: 109 | Type: AWS::IAM::InstanceProfile 110 | Condition: CreateManagedInstanceProfileCondition 111 | Properties: 112 | Path: "/" 113 | Roles: 114 | - !Ref ManagedInstanceRole 115 | InstanceProfileName: ManagedInstanceProfile 116 | 117 | #------------------------------------------------- 118 | # VPC and required resources to enable network connectivity to AWS Systems Manager 119 | #------------------------------------------------- 120 | VPC: 121 | Type: 'AWS::EC2::VPC' 122 | Properties: 123 | CidrBlock: 10.0.0.0/16 124 | EnableDnsSupport: true 125 | EnableDnsHostnames: true 126 | InstanceTenancy: default 127 | Tags: 128 | - Key: Name 129 | Value: Automation-CF 130 | InternetGateway: 131 | Type: 'AWS::EC2::InternetGateway' 132 | Properties: 133 | Tags: 134 | - Key: Name 135 | Value: Automation-CF 136 | VPCGatewayAttachment: 137 | Type: 'AWS::EC2::VPCGatewayAttachment' 138 | Properties: 139 | VpcId: !Ref VPC 140 | InternetGatewayId: !Ref InternetGateway 141 | SubnetPublic: 142 | Type: 'AWS::EC2::Subnet' 143 | Properties: 144 | AvailabilityZone: !Select [0, !GetAZs ''] 145 | CidrBlock: 10.0.0.0/20 146 | MapPublicIpOnLaunch: true 147 | VpcId: !Ref VPC 148 | Tags: 149 | - Key: Name 150 | Value: Automation-CF 151 | RouteTablePublic: 152 | Type: 'AWS::EC2::RouteTable' 153 | Properties: 154 | VpcId: !Ref VPC 155 | Tags: 156 | - Key: Name 157 | Value: Automation-CF 158 | RouteTableAssociationPublic: 159 | Type: 'AWS::EC2::SubnetRouteTableAssociation' 160 | Properties: 161 | SubnetId: !Ref SubnetPublic 162 | RouteTableId: !Ref RouteTablePublic 163 | RouteTablePublicInternetRoute: 164 | Type: 'AWS::EC2::Route' 165 | DependsOn: VPCGatewayAttachment 166 | Properties: 167 | RouteTableId: !Ref RouteTablePublic 168 | DestinationCidrBlock: '0.0.0.0/0' 169 | GatewayId: !Ref InternetGateway 170 | NetworkAclPublic: 171 | Type: 'AWS::EC2::NetworkAcl' 172 | Properties: 173 | VpcId: !Ref VPC 174 | Tags: 175 | - Key: Name 176 | Value: Automation-CF 177 | SubnetNetworkAclAssociationPublic: 178 | Type: 'AWS::EC2::SubnetNetworkAclAssociation' 179 | Properties: 180 | SubnetId: !Ref SubnetPublic 181 | NetworkAclId: !Ref NetworkAclPublic 182 | NetworkAclEntryInPublicAllowAll: 183 | Type: 'AWS::EC2::NetworkAclEntry' 184 | Properties: 185 | NetworkAclId: !Ref NetworkAclPublic 186 | RuleNumber: 100 187 | Protocol: -1 188 | RuleAction: allow 189 | Egress: false 190 | CidrBlock: '0.0.0.0/0' 191 | NetworkAclEntryOutPublicAllowAll: 192 | Type: 'AWS::EC2::NetworkAclEntry' 193 | Properties: 194 | NetworkAclId: !Ref NetworkAclPublic 195 | RuleNumber: 100 196 | Protocol: -1 197 | RuleAction: allow 198 | Egress: true 199 | CidrBlock: '0.0.0.0/0' 200 | InstanceSecurityGroup: 201 | Type: AWS::EC2::SecurityGroup 202 | Properties: 203 | GroupDescription: "Security Group for Automation patching test instances" 204 | GroupName: Automation-CF 205 | SecurityGroupEgress: 206 | - IpProtocol: -1 207 | FromPort: 0 208 | ToPort: 65535 209 | CidrIp: 0.0.0.0/0 210 | Tags: 211 | - Key: Name 212 | Value: Automation-CF 213 | VpcId: !Ref VPC 214 | 215 | #------------------------------------------------- 216 | # Linux and Windows test EC2 instances using the latest versions of Amazon Linux and Windows 2019 217 | #------------------------------------------------- 218 | LinuxEc2Instance: 219 | Type: AWS::EC2::Instance 220 | Properties: 221 | InstanceType: t2.small 222 | ImageId: !Ref LatestAmazonLinuxAmiId 223 | NetworkInterfaces: 224 | - AssociatePublicIpAddress: "true" 225 | DeviceIndex: "0" 226 | GroupSet: 227 | - Ref: "InstanceSecurityGroup" 228 | SubnetId: 229 | Ref: "SubnetPublic" 230 | IamInstanceProfile: 231 | Fn::If: 232 | - CreateManagedInstanceProfileCondition 233 | - !Ref ManagedInstanceProfile 234 | - !Ref ExistingManagedInstanceProfile 235 | Tags: 236 | - Key: Name 237 | Value: AmazonLinux 238 | - Key: Patch 239 | Value: 'True' 240 | - Key: 'Patch Group' 241 | Value: 'CustomAmazonLinux' 242 | WindowsEc2Instance: 243 | Type: AWS::EC2::Instance 244 | Properties: 245 | InstanceType: t2.small 246 | ImageId: !Ref LatestWindowsAmiId 247 | NetworkInterfaces: 248 | - AssociatePublicIpAddress: "true" 249 | DeviceIndex: "0" 250 | GroupSet: 251 | - Ref: "InstanceSecurityGroup" 252 | SubnetId: 253 | Ref: "SubnetPublic" 254 | IamInstanceProfile: 255 | Fn::If: 256 | - CreateManagedInstanceProfileCondition 257 | - !Ref ManagedInstanceProfile 258 | - !Ref ExistingManagedInstanceProfile 259 | Tags: 260 | - Key: Name 261 | Value: Windows 262 | - Key: Patch 263 | Value: 'True' 264 | - Key: 'Patch Group' 265 | Value: 'CustomWindows' --------------------------------------------------------------------------------