Skip to content

Commit 592671d

Browse files
authored
Merge pull request #2595 from chanshih/main
New Serverless Pattern - automate secrets manager tag
2 parents c3c714b + 77a4a1a commit 592671d

File tree

9 files changed

+404
-0
lines changed

9 files changed

+404
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*.swp
2+
package-lock.json
3+
__pycache__
4+
.pytest_cache
5+
.venv
6+
*.egg-info
7+
source.bat
8+
9+
# CDK asset staging directory
10+
.cdk.staging
11+
cdk.out
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
# Auto-tag creator's username to AWS Secrets Manager entries
3+
4+
Implements automatic tagging of AWS Secrets Manager entries with the creator's username. When users authenticated via AWS IAM Identity Center create secrets, their username is automatically added as a tag. This enables easier ownership tracking and management of secrets across the organization.
5+
6+
Eventbridge rule is configured to look for CreateSecret events to invoke a Lambda function to tag the secret with the creator's username.
7+
8+
# Deployment Instructions
9+
10+
Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
11+
12+
```
13+
git clone https://github.com/aws-samples/serverless-patterns
14+
```
15+
16+
Change directory to the pattern directory:
17+
18+
```
19+
cd automate-secrets-manager-tags
20+
```
21+
22+
To manually create a virtualenv on MacOS and Linux:
23+
24+
```
25+
$ python3 -m venv .venv
26+
```
27+
28+
After the init process completes and the virtualenv is created, you can use the following
29+
step to activate your virtualenv.
30+
31+
```
32+
$ source .venv/bin/activate
33+
```
34+
35+
If you are a Windows platform, you would activate the virtualenv like this:
36+
37+
```
38+
% .venv\Scripts\activate.bat
39+
```
40+
41+
Once the virtualenv is activated, you can install the required dependencies.
42+
43+
```
44+
$ pip install -r requirements.txt
45+
```
46+
47+
At this point you can now synthesize the CloudFormation template for this code.
48+
49+
```
50+
$ cdk synth
51+
```
52+
53+
## Deploy
54+
At this point you can deploy the stack.
55+
56+
Using the default profile
57+
58+
```
59+
$ cdk deploy
60+
```
61+
62+
With specific profile
63+
64+
```
65+
$ cdk deploy --profile test
66+
```
67+
68+
## Useful commands
69+
70+
* `cdk ls` list all stacks in the app
71+
* `cdk synth` emits the synthesized CloudFormation template
72+
* `cdk deploy` deploy this stack to your default AWS account/region
73+
* `cdk diff` compare deployed stack with current state
74+
* `cdk docs` open CDK documentation
75+
76+
## Testing
77+
78+
To test the automated tagging of secrets in AWS Secrets Manager, we will need to use the AWS console.
79+
80+
1. Login to AWS Console using AWS IAM Identity Center.
81+
2. Navigate to AWS Secrets Manager and create a secret.
82+
3. Open the "Tags" tab of the newly created secret to see the automated tag key=LoginUserName and value=<Username>.
83+
84+
## Cleanup
85+
86+
Run below script in the `automate-secrets-manager-tags` directory to delete AWS resources created by this sample stack.
87+
88+
```
89+
cdk destroy
90+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
6+
from stacks.main import AutomateSecretsManagerTagsStack
7+
8+
9+
app = cdk.App()
10+
AutomateSecretsManagerTagsStack(app, "AutomateSecretsManagerTagsStack")
11+
12+
app.synth()
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"title": "Automate creator username tags for AWS Secrets Manager secrets",
3+
"description": "Automate tagging of AWS Secrets Manager secrets with the creator's username",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "CDK",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This sample project demonstrates the automatic tagging of username to the secrets they created when user is authenticated via AWS IAM Identity Center. This enables easier ownership tracking and management of secrets across the organization.",
11+
"Eventbridge rule is configured to look for CreateSecret events to invoke a Lambda function to tag the secret with the creator's username."
12+
]
13+
},
14+
"gitHub": {
15+
"template": {
16+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/automate-secrets-manager-tags",
17+
"templateURL": "serverless-patterns/automate-secrets-manager-tags",
18+
"projectFolder": "automate-secrets-manager-tags",
19+
"templateFile": "stacks/main.py"
20+
}
21+
},
22+
"resources": {
23+
"bullets": [
24+
{
25+
"text": "Match AWS Secrets Manager events with Amazon EventBridge",
26+
"link": "https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring-eventbridge.html"
27+
}
28+
]
29+
},
30+
"deploy": {
31+
"text": [
32+
"cdk deploy"
33+
]
34+
},
35+
"testing": {
36+
"text": [
37+
"See the GitHub repo for detailed testing instructions."
38+
]
39+
},
40+
"cleanup": {
41+
"text": [
42+
"Delete the stack: <code>cdk destroy</code>."
43+
]
44+
},
45+
"authors": [
46+
{
47+
"name": "Chan Shi Hui",
48+
"image": "https://avatars.githubusercontent.com/u/103100403?v=4",
49+
"bio": "Shi Hui is a Technical Account Manager working at AWS Singapore to build, run, and scale customer workloads on AWS.",
50+
"linkedin": "chan-shi-hui-38915aa3"
51+
}
52+
],
53+
"patternArch": {
54+
"icon1": {
55+
"x": 20,
56+
"y": 50,
57+
"service": "secretsmanager",
58+
"label": "AWS Secrets Manager"
59+
},
60+
"icon2": {
61+
"x": 50,
62+
"y": 50,
63+
"service": "eventbridge",
64+
"label": "Amazon EventBridge"
65+
},
66+
"icon3": {
67+
"x": 80,
68+
"y": 50,
69+
"service": "lambda",
70+
"label": "AWS Lambda"
71+
},
72+
"line1": {
73+
"from": "icon1",
74+
"to": "icon2"
75+
},
76+
"line2": {
77+
"from": "icon2",
78+
"to": "icon3"
79+
}
80+
}
81+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"**/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
19+
"@aws-cdk/core:checkSecretUsage": true,
20+
"@aws-cdk/core:target-partitions": [
21+
"aws",
22+
"aws-cn"
23+
],
24+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
27+
"@aws-cdk/aws-iam:minimizePolicies": true,
28+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
33+
"@aws-cdk/core:enablePartitionLiterals": true,
34+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
35+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
36+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
37+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
38+
"@aws-cdk/aws-route53-patters:useCertificate": true,
39+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
40+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
41+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
42+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
43+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
44+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
45+
"@aws-cdk/aws-redshift:columnId": true,
46+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
47+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
48+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
49+
"@aws-cdk/aws-kms:aliasNameRef": true,
50+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
51+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
52+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
53+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
54+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
55+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
56+
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
57+
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
58+
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
59+
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
60+
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
61+
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
62+
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
63+
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
64+
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
65+
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
66+
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
67+
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
68+
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
69+
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
70+
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
71+
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
72+
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
73+
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
74+
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
75+
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
76+
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true
77+
}
78+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"title": "Automate creator username tags for AWS Secrets Manager secrets",
3+
"description": "Automate tagging of AWS Secrets Manager secrets with the creator's username",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "CDK",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This sample project demonstrates the automatic tagging of username to the secrets they created when user is authenticated via AWS IAM Identity Center. This enables easier ownership tracking and management of secrets across the organization.",
11+
"Eventbridge rule is configured to look for CreateSecret events to invoke a Lambda function to tag the secret with the creator's username."
12+
]
13+
},
14+
"gitHub": {
15+
"template": {
16+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/automate-secrets-manager-tags",
17+
"templateURL": "serverless-patterns/automate-secrets-manager-tags",
18+
"projectFolder": "automate-secrets-manager-tags",
19+
"templateFile": "automate-secrets-manager-tags.py"
20+
}
21+
},
22+
"resources": {
23+
"bullets": [
24+
{
25+
"text": "Match AWS Secrets Manager events with Amazon EventBridge",
26+
"link": "https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring-eventbridge.html"
27+
}
28+
]
29+
},
30+
"deploy": {
31+
"text": [
32+
"cdk deploy"
33+
]
34+
},
35+
"testing": {
36+
"text": [
37+
"See the GitHub repo for detailed testing instructions."
38+
]
39+
},
40+
"cleanup": {
41+
"text": [
42+
"Delete the stack: <code>cdk destroy</code>."
43+
]
44+
},
45+
"authors": [
46+
{
47+
"name": "Chan Shi Hui",
48+
"image": "https://avatars.githubusercontent.com/u/103100403?v=4",
49+
"bio": "Shi Hui is a Technical Account Manager working at AWS Singapore to build, run, and scale customer workloads on AWS.",
50+
"linkedin": "chan-shi-hui-38915aa3"
51+
}
52+
]
53+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import json
2+
import boto3
3+
4+
secrets_manager_client = boto3.client('secretsmanager')
5+
6+
def lambda_handler(event, context):
7+
# Extract user info from the EventBridge event
8+
try:
9+
principalId = event['detail']['userIdentity']['principalId']
10+
print(f'principalId:{principalId}')
11+
user_name = principalId.split(":")[1]
12+
13+
except KeyError:
14+
print("Error: Could not extract user name from event")
15+
return
16+
17+
secret_name = event['detail']['requestParameters']['name']
18+
19+
try:
20+
# Apply a tag to the secret
21+
secrets_manager_client.tag_resource(
22+
SecretId=secret_name,
23+
Tags=[
24+
{
25+
'Key': 'LoginUserName',
26+
'Value': user_name
27+
}
28+
]
29+
)
30+
print(f"Successfully tagged secret {secret_name} with username {user_name}")
31+
except Exception as e:
32+
print(f"Error tagging secret: {str(e)}")
33+
raise e
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-cdk-lib==2.176.0
2+
constructs>=10.0.0,<11.0.0

0 commit comments

Comments
 (0)