AWS Cloud Operations Blog
Centralized Dashboard for AWS Config and AWS Security Hub
Back in July 2022, we announced AWS config compliance scores for conformance packs which helps you quantify your compliance posture as an Amazon CloudWatch metric. It’s a quantitative measure of compliance status. While customers can have hundreds of AWS accounts where AWS Config is enabled and each account and each AWS Region have a different compliance score. While we can currently track the compliance status with an aggregated score, it is important to look at compliance scores for every account and every region to check the progress made by every team.
AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you assess your AWS environment against security industry standards and best practices. AWS Security Hub uses service-linked rules from AWS Config to run security checks for most controls. Security Hub also displays a security score from 0–100 percent for each enabled standard.
In this blog post, we will show you how you can create Amazon CloudWatch Dashboard using a custom metric to have a centralized dashboard for monitoring multi-account , multi-Region compliance scores for AWS Config and also for AWS Security Hub.
Architecture
Prerequisites
To utilize our solution, you need the following tools:
- AWS CLI – Install the AWS CLI
- SAM CLI – Install the SAM CLI. 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.
- Python 3.8 – Install Python
Download the solution
git clone https://github.com/aws-samples/aws-centralized-dashboard-config-securityhub.git
The application has 2 directories:
- aws_status_check_app – A SAM Application with AWS Lambda functions and AWS CloudFormation Template (template.yaml) to deploy the resources by using SAM CLI. This application is deployed in the AWS Organization management account.
- StacksetCFTemplate – This directory contains an AWS CloudFormation StackSet templatefile that defines the IAM Role and IAM Policy deployed on the member accounts. This IAM Policy and IAM Role is necessary on the member accounts for the application to assumeRole and gather AWS service status.
How to build and deploy this application
- Build the application with the
sam build
command after navigating into the aws_status_check_app directory. - This second command will package and deploy your application to AWS, with a series of prompts:
- Stack Name: aws-status-check-app
- AWS Region: – AWS Region where this solution will be deployed.
- Parameter CheckFrequencyInterval – This parameter defines how often the Lambda function executes to check for the AWS Config status. Allowed Values are “rate(1 day)”, “rate(12 hours)”, “rate(6 hours)”, “rate(3 hours)”, “rate(1 hour)”.
- Parameter CheckAllAccountsinOrgCondition – If set to true, MemberAccountIds Parameter is ignored, and the application checks the status of AWS Config in all accounts/regions across the AWS Organization. If set to false, proceed to setting the MemberAccountIds parameter. Allowed values are “true” or “false”.
- Parameter MemberAccountIds – If parameter CheckAllAccountsinOrgCondition is set to false, enter a comma separated list of AWS account ids where you want the application to check for AWS Config Status. Leave this parameter to its default value, if you set CheckAllAccountsinOrgCondition to true. [Eg: 12345634344,434345555333,455454545324]
- 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.
- Allow SAM CLI IAM role creation: To deploy this application’s AWS CloudFormation stack which creates or modifies IAM roles, the
CAPABILITY_IAM
value forcapabilities
must be provided. If permission isn’t provided through this prompt, to deploy this example you must explicitly pass--capabilities CAPABILITY_IAM
to thesam deploy
command. - 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. - Create an AWS CloudFormation StackSet using AWS CLI. Make sure you have the required permissions for stack sets operations. Provide the AWS management account ID where this StackSet will be deployed
- Create an AWS CloudFormation Stack Instances by using AWS CLI. Provide the OrganizationalUnitIds of the member accounts to which the stack instances are deployed.
cd aws_status_check_app
sam build
Sample Output:
aws_status_check_app$ sam build
Building codeuri: /local/home/sundjega/centraldashboard/aws-centralized-dashboard-config-securityhub/aws_status_check_app/aws_status_check runtime: python3.8 metadata: {} architecture: x86_64 functions: ManagerFunction, WorkerFunction
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
sam deploy --guided --capabilities CAPABILITY_NAMED_IAM
sample output:
aws_status_check_app$ sam deploy --guided --capabilities CAPABILITY_NAMED_IAM
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: aws-status-check-app
AWS Region [us-east-1]: us-east-2
Parameter CheckFrequencyMins [rate(1 day)]: rate(1 day)
Parameter CheckAllAccountsinOrgCondition [true]:
Parameter MemberAccountIds [IGNORE,IF,CheckAllAccountsinOrg,TRUE]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: Y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: y
Save arguments to configuration file [Y/n]: Y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1bctiwbckuz4w
A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.thinkwithwp.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Uploading to aws-status-check-app/260bddab803770c56a539cca40ce28d9 4509 / 4509 (100.00%)
File with same data already exists at aws-status-check-app/260bddab803770c56a539cca40ce28d9, skipping upload
Deploying with following values
===============================
Stack name : aws-status-check-app
Region : us-east-2
Confirm changeset : True
Disable rollback : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-1bctiwbckuz4w
Capabilities : ["CAPABILITY_NAMED_IAM"]
Parameter overrides : {"CheckFrequencyMins": "rate(1 day)", "CheckAllAccountsinOrgCondition": "true", "MemberAccountIds": "IGNORE,IF,CheckAllAccountsinOrg,TRUE"}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to aws-status-check-app/752cc090fa93293635f6b8f07888fe5a.template 7794 / 7794 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add AppFunctionPolicy AWS::IAM::ManagedPolicy N/A
+ Add AppFunctionRole AWS::IAM::Role N/A
+ Add AssumedFunctionRole AWS::IAM::Role N/A
+ Add CheckAllAccountsinOrgParameter AWS::SSM::Parameter N/A
+ Add ConfigAccountsParameter AWS::SSM::Parameter N/A
+ Add ManagerFunctionLogGroup AWS::Logs::LogGroup N/A
+ Add ManagerFunctionScheduledRule AWS::Events::Rule N/A
+ Add ManagerFunction AWS::Lambda::Function N/A
+ Add PermissionForEventsToInvokeLambda1 AWS::Lambda::Permission N/A
+ Add PermissionForEventsToInvokeLambda2 AWS::Lambda::Permission N/A
+ Add WorkerFunctionLogGroup AWS::Logs::LogGroup N/A
+ Add WorkerFunctionRule AWS::Events::Rule N/A
+ Add WorkerFunction AWS::Lambda::Function N/A
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:us-east-2:xxxxxxxxxxxxxx:changeSet/samcli-deploy1690484417/bbcba1ce-e8ca-4ecc-b1a6-b12beca2aaa2
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2023-07-27 19:00:26 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 5.0 seconds)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::IAM::ManagedPolicy AppFunctionPolicy -
CREATE_IN_PROGRESS AWS::SSM::Parameter ConfigAccountsParameter -
CREATE_IN_PROGRESS AWS::Logs::LogGroup WorkerFunctionLogGroup -
CREATE_IN_PROGRESS AWS::SSM::Parameter CheckAllAccountsinOrgParameter -
CREATE_IN_PROGRESS AWS::Logs::LogGroup ManagerFunctionLogGroup -
CREATE_IN_PROGRESS AWS::IAM::ManagedPolicy AppFunctionPolicy Resource creation Initiated
CREATE_IN_PROGRESS AWS::SSM::Parameter ConfigAccountsParameter Resource creation Initiated
CREATE_IN_PROGRESS AWS::Logs::LogGroup WorkerFunctionLogGroup Resource creation Initiated
CREATE_IN_PROGRESS AWS::SSM::Parameter CheckAllAccountsinOrgParameter Resource creation Initiated
CREATE_IN_PROGRESS AWS::Logs::LogGroup ManagerFunctionLogGroup Resource creation Initiated
CREATE_COMPLETE AWS::Logs::LogGroup WorkerFunctionLogGroup -
CREATE_COMPLETE AWS::SSM::Parameter ConfigAccountsParameter -
CREATE_COMPLETE AWS::Logs::LogGroup ManagerFunctionLogGroup -
CREATE_COMPLETE AWS::SSM::Parameter CheckAllAccountsinOrgParameter -
CREATE_COMPLETE AWS::IAM::ManagedPolicy AppFunctionPolicy -
CREATE_IN_PROGRESS AWS::IAM::Role AppFunctionRole -
CREATE_IN_PROGRESS AWS::IAM::Role AssumedFunctionRole -
CREATE_IN_PROGRESS AWS::IAM::Role AppFunctionRole Resource creation Initiated
CREATE_IN_PROGRESS AWS::IAM::Role AssumedFunctionRole Resource creation Initiated
CREATE_COMPLETE AWS::IAM::Role AssumedFunctionRole -
CREATE_COMPLETE AWS::IAM::Role AppFunctionRole -
CREATE_IN_PROGRESS AWS::Lambda::Function WorkerFunction -
CREATE_IN_PROGRESS AWS::Lambda::Function ManagerFunction -
CREATE_IN_PROGRESS AWS::Lambda::Function WorkerFunction Resource creation Initiated
CREATE_IN_PROGRESS AWS::Lambda::Function ManagerFunction Resource creation Initiated
CREATE_COMPLETE AWS::Lambda::Function WorkerFunction -
CREATE_COMPLETE AWS::Lambda::Function ManagerFunction -
CREATE_IN_PROGRESS AWS::Events::Rule WorkerFunctionRule -
CREATE_IN_PROGRESS AWS::Events::Rule ManagerFunctionScheduledRule -
CREATE_IN_PROGRESS AWS::Events::Rule ManagerFunctionScheduledRule Resource creation Initiated
CREATE_IN_PROGRESS AWS::Events::Rule WorkerFunctionRule Resource creation Initiated
CREATE_COMPLETE AWS::Events::Rule ManagerFunctionScheduledRule -
CREATE_COMPLETE AWS::Events::Rule WorkerFunctionRule -
CREATE_IN_PROGRESS AWS::Lambda::Permission PermissionForEventsToInvokeLambda1 -
CREATE_IN_PROGRESS AWS::Lambda::Permission PermissionForEventsToInvokeLambda2 -
CREATE_IN_PROGRESS AWS::Lambda::Permission PermissionForEventsToInvokeLambda1 Resource creation Initiated
CREATE_IN_PROGRESS AWS::Lambda::Permission PermissionForEventsToInvokeLambda2 Resource creation Initiated
CREATE_COMPLETE AWS::Lambda::Permission PermissionForEventsToInvokeLambda1 -
CREATE_COMPLETE AWS::Lambda::Permission PermissionForEventsToInvokeLambda2 -
CREATE_COMPLETE AWS::CloudFormation::Stack aws-status-check-app -
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key ManagerFunctionARN
Description ManagerFunction ARN
Value arn:aws:lambda:us-east-2:xxxxxxxxxxxxxx:function:aws-status-check-app-ManagerFunction-oXx2fvZGftLJ
Key WorkerFunctionARN
Description WorkerFunction ARN
Value arn:aws:lambda:us-east-2:xxxxxxxxxxxxxx:function:aws-status-check-app-WorkerFunction-HBY2theGkFFj
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - aws-status-check-app in us-east-2
cd ../StacksetCFTemplate
aws cloudformation create-stack-set \
--description "role/policies for aws config checker" \
--stack-set-name aws-status-checker-stackset \
--template-body file://stacksettemplate.yml \
--permission-model SERVICE_MANAGED \
--capabilities CAPABILITY_NAMED_IAM \
--parameters ParameterKey=AdministratorAccountId,ParameterValue=<AWS_ManagementAccountId> \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false
sample output:
aws cloudformation create-stack-set \
> --description "role/policies for aws config checker" \
> --stack-set-name aws-status-checker-stackset \
> --template-body file://stacksettemplate.yml \
> --permission-model SERVICE_MANAGED \
> --capabilities CAPABILITY_NAMED_IAM \
> --parameters ParameterKey=AdministratorAccountId,ParameterValue=xxxxxxxxxx \
> --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false
{
"StackSetId": "aws-config-checker-stackset:273c07d1-c7ab-4e6c-b388-0f6e2263c400"
}
aws cloudformation create-stack-instances \
--deployment-targets OrganizationalUnitIds=[Organizational_Unit_Ids] \
--stack-set-name aws-status-checker-stackset --regions us-east-2
sample output:
StacksetCFTemplate$ aws cloudformation create-stack-instances \
> --deployment-targets OrganizationalUnitIds=r-xxxx \
> --stack-set-name aws-status-checker-stackset --regions us-east-2
{
"OperationId": "1e740a93-e980-44e0-a4d6-6747384dab2f"
}
Troubleshooting the Lambda function
-
In order 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 useful features to help you quickly find the bug.
sam logs -n WorkerFunction --stack-name aws-status-check-app --tail
sam logs -n ManagerFunction --stack-name aws-status-check-app --tail
Create CloudWatch Dashboard using custom metrics
- After a few minutes, log in to the Amazon CloudWatch console to view custom metrics under the Custom namespace named CustomMetrics/Config and CustomMetrics/SecurityHub.
- Follow the steps here to create CloudWatch dashboard from custom metrics. Below is the sample centralized dashboard for compliance scores and Security Hub security score.
Cleanup
- To delete the awsstatuscheck application that you created, use the SAM CLI.
- Delete the Stack Instances from AWS CloudFormation StackSet using AWS CLI.
- Wait for Step 2 to finish. Then, delete the AWS CloudFormation StackSet using AWS CLI.
sam delete
sample output:
aws_status_check_app $ sam delete
Are you sure you want to delete the stack aws-status-checker-stackset in the region us-east-2 ? [y/N]: y
Are you sure you want to delete the folder aws-status-check-app in S3 which contains the artifacts? [y/N]: y
- Deleting S3 object with key aws-status-check-app/aca923a2899ecef9bb25fc9d708b2067
- Could not find and delete the S3 object with the key aws-status-check-app/aca923a2899ecef9bb25fc9d708b2067
- Deleting S3 object with key aws-status-check-app/23b0a7ffd14c825f099b0d67a2d1ae18.template
- Deleting S3 object with key aws-status-check-app/26d62b2b9477b02ff57126cd6a59be0b.template
- Deleting S3 object with key aws-status-check-app/938f74b20506773321240e7555ac4910.template
- Deleting S3 object with key aws-status-check-app/93c76ece26e084135707d1b4b26f053b.template
- Deleting S3 object with key aws-status-check-app/b93be3ce737bcac83d43d92246689245.template
- Deleting S3 object with key aws-status-check-app/f81beb0c1361619d6542ef6017556482.template
- Deleting Cloudformation stack aws-status-check-app
Deleted successfully
aws cloudformation delete-stack-instances --stack-set-name aws-status-checker-stackset --regions us-east-2 --no-retain-stacks --deployment-targets OrganizationalUnitIds=[Organizational_Unit_Ids]
aws cloudformation delete-stack-set --stack-set-name aws-status-checker-stackset
Conclusion
-
In this blog post, we showed you how to create custom metrics to create a centralized dashboard for monitoring multi-account, multi-Region compliance scores for AWS Config and also for AWS Security hub. We further used these custom metrics to create a centralized security dashboard using Amazon CloudWatch dashboard.