Feature/aws config#466
Open
siddarthancha wants to merge 11 commits into
Open
Conversation
- Add ConformancePack construct for account-level deployment - Add OrganizationConformancePack for organization-wide deployment - Add ConfigRecorder and DeliveryChannel constructs - Support 60+ compliance frameworks (HIPAA, PCI-DSS, NIST, CIS, etc.) - Automatic template fetching from AWS Labs repository - Complete documentation and usage examples
There was a problem hiding this comment.
Pull request overview
This PR adds a new aws-config module to the truemark-cdk-lib CDK library, including constructs for AWS Config recorders/delivery channels and (organization) conformance pack deployment, along with documentation and packaging/exports updates.
Changes:
- Added
ConformancePackandOrganizationConformancePackconstructs with support for fetching AWS Labs conformance pack templates. - Added
ConfigRecorderandDeliveryChannelconstructs plus a comprehensiveaws-configREADME and example stack file. - Wired the new module into library exports (
cdk/src/index.ts) and npm package subpath exports (cdk/package.json).
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| cdk/src/index.ts | Exports the new aws-config module from the library root. |
| cdk/src/aws-config/lib/conformance-pack.ts | Adds account-level conformance pack construct with template fetching support. |
| cdk/src/aws-config/lib/organization-conformance-pack.ts | Adds org-level conformance pack construct with template fetching + excluded accounts. |
| cdk/src/aws-config/lib/config-recorder.ts | Adds AWS Config recorder and delivery channel constructs. |
| cdk/src/aws-config/lib/conformance-pack-templates.ts | Adds mapping + URL builder for AWS Labs conformance pack templates. |
| cdk/src/aws-config/lib/index.ts | Barrel exports for the new module’s constructs/utilities. |
| cdk/src/aws-config/index.ts | Module entrypoint export. |
| cdk/src/aws-config/README.md | Usage docs, pack list, and API reference for the new module. |
| cdk/examples/aws-config-example.ts | Example stacks demonstrating typical usage patterns. |
| cdk/package.json | Adds ./aws-config subpath export and typesVersions mapping. |
| CODEOWNERS | Adds a CODEOWNERS rule for the CDK directory. |
| .idea/git_toolbox_prj.xml | Adds IDE plugin project settings. |
| .idea/awsToolkit.xml | Adds IDE AWS Toolkit region configuration. |
Files not reviewed (2)
- .idea/awsToolkit.xml: Language not supported
- .idea/git_toolbox_prj.xml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ### OrganizationConformancePack | ||
|
|
||
| ```typescript | ||
| interface OrganizationConformancePackProps extends ConformancePackProps { |
| @@ -1 +1,2 @@ | |||
| * @truemark/truemark | |||
| cdk/* @erikrj | |||
Comment on lines
+144
to
+213
| const fetchTemplateLambda = new LambdaFunction(this, 'FetchTemplate', { | ||
| runtime: Runtime.NODEJS_20_X, | ||
| handler: 'index.handler', | ||
| code: Code.fromInline(` | ||
| const https = require('https'); | ||
|
|
||
| exports.handler = async (event) => { | ||
| console.log('Request:', JSON.stringify(event, null, 2)); | ||
|
|
||
| if (event.RequestType === 'Delete') { | ||
| return sendResponse(event, 'SUCCESS', {}); | ||
| } | ||
|
|
||
| const url = event.ResourceProperties.TemplateUrl; | ||
|
|
||
| try { | ||
| const template = await fetchTemplate(url); | ||
| const responseData = { | ||
| TemplateBody: template | ||
| }; | ||
| return sendResponse(event, 'SUCCESS', responseData); | ||
| } catch (error) { | ||
| console.error('Error fetching template:', error); | ||
| return sendResponse(event, 'FAILED', {}, error.message); | ||
| } | ||
| }; | ||
|
|
||
| function fetchTemplate(url) { | ||
| return new Promise((resolve, reject) => { | ||
| https.get(url, (res) => { | ||
| let data = ''; | ||
| res.on('data', (chunk) => { data += chunk; }); | ||
| res.on('end', () => { | ||
| if (res.statusCode === 200) { | ||
| resolve(data); | ||
| } else { | ||
| reject(new Error(\`HTTP \${res.statusCode}: \${data}\`)); | ||
| } | ||
| }); | ||
| }).on('error', reject); | ||
| }); | ||
| } | ||
|
|
||
| function sendResponse(event, responseStatus, responseData, reason) { | ||
| return { | ||
| Status: responseStatus, | ||
| Reason: reason || 'See CloudWatch logs', | ||
| PhysicalResourceId: event.PhysicalResourceId || event.LogicalResourceId, | ||
| StackId: event.StackId, | ||
| RequestId: event.RequestId, | ||
| LogicalResourceId: event.LogicalResourceId, | ||
| Data: responseData | ||
| }; | ||
| } | ||
| `), | ||
| timeout: Duration.seconds(30), | ||
| }); | ||
|
|
||
| const provider = new Provider(this, 'FetchTemplateProvider', { | ||
| onEventHandler: fetchTemplateLambda, | ||
| }); | ||
|
|
||
| const templateUrl = | ||
| props.templateS3Uri ?? | ||
| getConformancePackTemplateUrl( | ||
| props.packName, | ||
| props.templateVersion, | ||
| props.templateRepositoryUrl, | ||
| ); | ||
|
|
Comment on lines
+62
to
+65
| recordingGroup: { | ||
| allSupported: props.recordAllSupported ?? true, | ||
| includeGlobalResourceTypes: props.includeGlobalResourceTypes ?? true, | ||
| }, |
Comment on lines
+17
to
+89
| export interface OrganizationConformancePackProps { | ||
| /** | ||
| * The name of the conformance pack. This should be one of the predefined | ||
| * pack names from CONFORMANCE_PACK_TEMPLATES or a custom name if providing | ||
| * a custom template. | ||
| */ | ||
| readonly packName: string; | ||
|
|
||
| /** | ||
| * Optional prefix to add to the conformance pack name. | ||
| * @default - No prefix | ||
| */ | ||
| readonly packNamePrefix?: string; | ||
|
|
||
| /** | ||
| * Custom template body for the conformance pack. | ||
| * If not provided, the template will be fetched from AWS Labs repository | ||
| * based on the packName. | ||
| * @default - Fetches template from AWS Labs repository | ||
| */ | ||
| readonly templateBody?: string; | ||
|
|
||
| /** | ||
| * Template URL for the conformance pack. | ||
| * If not provided and templateBody is not provided, it will be constructed | ||
| * from the packName. | ||
| * @default - Constructed from packName | ||
| */ | ||
| readonly templateS3Uri?: string; | ||
|
|
||
| /** | ||
| * Template version to use (commit hash, tag, or 'latest'). | ||
| * Only used if templateBody is not provided. | ||
| * @default 'latest' | ||
| */ | ||
| readonly templateVersion?: string; | ||
|
|
||
| /** | ||
| * Base URL for the conformance pack templates repository. | ||
| * @default 'https://raw.githubusercontent.com/awslabs/aws-config-rules' | ||
| */ | ||
| readonly templateRepositoryUrl?: string; | ||
|
|
||
| /** | ||
| * Input parameters for the conformance pack. | ||
| * @default - No input parameters | ||
| */ | ||
| readonly inputParameters?: ConformancePackInputParameters; | ||
|
|
||
| /** | ||
| * S3 bucket for AWS Config delivery. | ||
| * @default - No S3 bucket for delivery | ||
| */ | ||
| readonly deliveryBucket?: IBucket; | ||
|
|
||
| /** | ||
| * Name of the S3 bucket for AWS Config delivery. | ||
| * @default - No S3 bucket for delivery | ||
| */ | ||
| readonly deliveryBucketName?: string; | ||
|
|
||
| /** | ||
| * S3 key prefix for AWS Config delivery channel. | ||
| * @default 'config' | ||
| */ | ||
| readonly deliveryS3KeyPrefix?: string; | ||
|
|
||
| /** | ||
| * AWS accounts to exclude from the conformance pack. | ||
| * @default - No excluded accounts | ||
| */ | ||
| readonly excludedAccounts?: string[]; | ||
| } |
Comment on lines
+152
to
+213
| const fetchTemplateLambda = new LambdaFunction(this, 'FetchTemplate', { | ||
| runtime: Runtime.NODEJS_20_X, | ||
| handler: 'index.handler', | ||
| code: Code.fromInline(` | ||
| const https = require('https'); | ||
|
|
||
| exports.handler = async (event) => { | ||
| console.log('Request:', JSON.stringify(event, null, 2)); | ||
|
|
||
| if (event.RequestType === 'Delete') { | ||
| return sendResponse(event, 'SUCCESS', {}); | ||
| } | ||
|
|
||
| const url = event.ResourceProperties.TemplateUrl; | ||
|
|
||
| try { | ||
| const template = await fetchTemplate(url); | ||
| const responseData = { | ||
| TemplateBody: template | ||
| }; | ||
| return sendResponse(event, 'SUCCESS', responseData); | ||
| } catch (error) { | ||
| console.error('Error fetching template:', error); | ||
| return sendResponse(event, 'FAILED', {}, error.message); | ||
| } | ||
| }; | ||
|
|
||
| function fetchTemplate(url) { | ||
| return new Promise((resolve, reject) => { | ||
| https.get(url, (res) => { | ||
| let data = ''; | ||
| res.on('data', (chunk) => { data += chunk; }); | ||
| res.on('end', () => { | ||
| if (res.statusCode === 200) { | ||
| resolve(data); | ||
| } else { | ||
| reject(new Error(\`HTTP \${res.statusCode}: \${data}\`)); | ||
| } | ||
| }); | ||
| }).on('error', reject); | ||
| }); | ||
| } | ||
|
|
||
| function sendResponse(event, responseStatus, responseData, reason) { | ||
| return { | ||
| Status: responseStatus, | ||
| Reason: reason || 'See CloudWatch logs', | ||
| PhysicalResourceId: event.PhysicalResourceId || event.LogicalResourceId, | ||
| StackId: event.StackId, | ||
| RequestId: event.RequestId, | ||
| LogicalResourceId: event.LogicalResourceId, | ||
| Data: responseData | ||
| }; | ||
| } | ||
| `), | ||
| timeout: Duration.seconds(30), | ||
| }); | ||
|
|
||
| const provider = new Provider(this, 'FetchTemplateProvider', { | ||
| onEventHandler: fetchTemplateLambda, | ||
| }); | ||
|
|
| }); | ||
| } | ||
|
|
||
| this.conformancePackArn = this.conformancePack.ref; |
| ); | ||
| } | ||
|
|
||
| this.conformancePackArn = this.conformancePack.ref; |
Comment on lines
+206
to
+227
| const templateUrl = | ||
| props.templateS3Uri ?? | ||
| getConformancePackTemplateUrl( | ||
| props.packName, | ||
| props.templateVersion, | ||
| props.templateRepositoryUrl, | ||
| ); | ||
|
|
||
| const fetchedTemplate = new CustomResource(this, 'FetchedTemplate', { | ||
| serviceToken: provider.serviceToken, | ||
| properties: { | ||
| TemplateUrl: templateUrl, | ||
| }, | ||
| }); | ||
|
|
||
| this.conformancePack = new CfnConformancePack(this, 'Resource', { | ||
| conformancePackName: this.conformancePackName, | ||
| templateBody: fetchedTemplate.getAttString('TemplateBody'), | ||
| deliveryS3Bucket: deliveryBucketName, | ||
| deliveryS3KeyPrefix: deliveryBucketName | ||
| ? (props.deliveryS3KeyPrefix ?? 'config') | ||
| : undefined, |
Comment on lines
+45
to
+52
| /** | ||
| * Template URL for the conformance pack. | ||
| * If not provided and templateBody is not provided, it will be constructed | ||
| * from the packName. | ||
| * @default - Constructed from packName | ||
| */ | ||
| readonly templateS3Uri?: string; | ||
|
|
…upport - Fix conformance pack to work without delivery bucket (Control Tower compatible) - Add templateS3Uri support to avoid Custom Resource size limits - Successfully tested PCI DSS 4.0 deployment - Clean up temporary test files
…nformancePackProps - Remove duplicate field definitions - OrganizationConformancePackProps now properly extends ConformancePackProps - Matches documentation in README.md - Improves code maintainability and type safety
- Rename conformancePackArn to conformancePackId (Ref returns name, not ARN) - Add validation for recordAllSupported=false (requires additional config) - Improve documentation accuracy for return values - OrganizationConformancePackProps already extends ConformancePackProps
- Remove web-acl-builder.test.ts (implementation missing) - Remove WAFv2 examples and guide - Keep feature/aws-config branch focused on AWS Config module only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.