-
Notifications
You must be signed in to change notification settings - Fork 1
New: [AEA-6258] - Add SSM Parameter construct #619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 32 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
02b0af2
refactor: api gateway from cpt for reuse
tstephen-nhs 455b657
Merge branch 'main' into aea-6254-cdk-api-gateway
tstephen-nhs 26fbada
feat: add state machine construct inc. api gateway endpoint
tstephen-nhs db95a9f
chore: fix 'any' use
tstephen-nhs d3594ca
Merge branch 'main' into aea-6254-cdk-api-gateway
tstephen-nhs f3a9207
Add a construct that creates a batch of SSM parameters, thier outputs…
wildjames c7dbb39
Hack around sonar complaint
wildjames f7e421d
Add some validation around parameters being unique, and unit tests wr…
wildjames 2afccf1
Fallback to non optional descriptions and names
wildjames dc6f2d3
Merge in aea-6256-cdk-statemachine
wildjames bb83c29
fix: enforce expected role
tstephen-nhs 74d0de2
fix: make LogGroup child of API gateway
tstephen-nhs c7d714d
chore: add sonarqube plugin for 'clean as you code'
tstephen-nhs f2e9325
fix: protect against enabling csoc with no destination
tstephen-nhs 0ac46b1
chore: clean imports
tstephen-nhs b500519
chore: ignore SQ rather than add extra var declaration
tstephen-nhs 734254b
docs: JS doc
tstephen-nhs e26e480
docs: example of ApiGateway use
tstephen-nhs 50ebe0a
Merge branch 'aea-6254-cdk-api-gateway' into aea-6258-ssm-parameters
wildjames bd610d0
refactor: centralise constants
tstephen-nhs 4912c82
Add jsdocs to the construct
wildjames a784142
Allow a fallback value on get env var
wildjames 7b17511
Allow default values in env vars. Tests
wildjames 503d44c
Merge branch 'main' into aea-6254-cdk-api-gateway
tstephen-nhs 0ae7177
revert git secrets install
tstephen-nhs 2b92465
fix: use postCreate to avoid git-secrets failing on second and subseq…
tstephen-nhs 70e7f20
docs: add copilot instructions and teach it to write JSDoc
tstephen-nhs a5a01ac
Merge branch 'main' into aea-6254-cdk-api-gateway
tstephen-nhs 3176a52
chore: adopt latest get-repo-config.yml
tstephen-nhs 87cba70
chore: strip comment from devcontainer.json
tstephen-nhs dcab80b
Merge in latest from Tims branch
wildjames 1f2297d
Resolve conflicts
wildjames f5a4f8d
Run linter
wildjames d15b6f7
Go away sonar
wildjames 92376db
Address comments
wildjames File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |
| * @returns API Gateway request mapping template for StartExecution payloads. | ||
| */ | ||
| export const stateMachineRequestTemplate = (stateMachineArn: string) => { | ||
| return `## Velocity Template used for API Gateway request mapping template | ||
| return `## Velocity Template used for API Gateway request mapping template | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this one was correct before? 2 space indent |
||
| ## "@@" is used here as a placeholder for '"' to avoid using escape characters. | ||
|
|
||
| #set($includeHeaders = true) | ||
|
|
||
172 changes: 172 additions & 0 deletions
172
packages/cdkConstructs/src/constructs/SsmParametersConstruct.ts
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| import {CfnOutput} from "aws-cdk-lib" | ||
| import {Effect, ManagedPolicy, PolicyStatement} from "aws-cdk-lib/aws-iam" | ||
| import {StringParameter} from "aws-cdk-lib/aws-ssm" | ||
| import {Construct} from "constructs" | ||
|
|
||
| /** | ||
| * Definition for a single SSM String parameter and its output export metadata. | ||
| * | ||
| * @property id Unique identifier used for construct and output logical IDs. | ||
| * @property nameSuffix Suffix appended to stackName to create the parameter name. | ||
| * The final SSM parameter name is `${stackName}-${nameSuffix}`. | ||
| * @property description Description stored with the SSM parameter. | ||
|
wildjames marked this conversation as resolved.
|
||
| * @property value Value stored in the SSM parameter. | ||
| * @property outputExportSuffix Optional export suffix for the output containing | ||
| * the parameter name. Defaults to `nameSuffix`. | ||
| * @property outputDescription Optional output description. Defaults to | ||
| * `description`. | ||
| */ | ||
| export interface SsmParameterDefinition { | ||
| /** | ||
| * Unique identifier used for construct and output logical IDs. | ||
| */ | ||
| readonly id: string | ||
| /** | ||
| * Suffix appended to stackName to create the parameter name. | ||
| * The final SSM parameter name is `${stackName}-${nameSuffix}`. | ||
| */ | ||
| readonly nameSuffix: string | ||
| /** | ||
| * Description stored with the SSM parameter. | ||
| */ | ||
| readonly description: string | ||
| /** | ||
| * Value stored in the SSM parameter. | ||
| */ | ||
| readonly value: string | ||
| /** | ||
| * Optional export suffix for the output containing the parameter name. | ||
| * @default nameSuffix value | ||
| */ | ||
| readonly outputExportSuffix?: string | ||
| /** | ||
| * Optional output description. | ||
| * @default description value | ||
| */ | ||
| readonly outputDescription?: string | ||
| } | ||
|
|
||
| /** | ||
| * Properties used to configure {@link SsmParametersConstruct}. | ||
| * | ||
| * @property namePrefix Prefix used in SSM parameter names and CloudFormation | ||
| * export names. | ||
| * @property parameters List of SSM parameters to create. | ||
| * @property readPolicyDescription Description for the managed policy that grants | ||
| * read access. Defaults to "Allows reading SSM parameters". | ||
| * @property readPolicyOutputDescription Description for the output exporting the | ||
| * managed policy ARN. Defaults to "Access to the parameters used by the integration". | ||
| * @property readPolicyExportSuffix Export suffix for the output exporting the | ||
| * managed policy ARN. | ||
| */ | ||
| export interface SsmParametersConstructProps { | ||
| /** | ||
| * Prefix used in SSM parameter names and CloudFormation export names. | ||
| */ | ||
| readonly namePrefix: string | ||
| /** | ||
| * List of SSM parameters to create. | ||
| */ | ||
| readonly parameters: Array<SsmParameterDefinition> | ||
|
wildjames marked this conversation as resolved.
|
||
| /** | ||
| * Description for the managed policy that grants read access. | ||
| * @default "Allows reading SSM parameters" | ||
| */ | ||
| readonly readPolicyDescription?: string | ||
| /** | ||
| * Description for the output exporting the managed policy ARN. | ||
| * @default "Access to the parameters used by the integration" | ||
| */ | ||
| readonly readPolicyOutputDescription?: string | ||
| /** | ||
| * Export suffix for the output exporting the managed policy ARN. | ||
| */ | ||
| readonly readPolicyExportSuffix: string | ||
| } | ||
|
|
||
| /** | ||
| * Creates a bundle of SSM String parameters, a managed policy to read them, | ||
| * and CloudFormation outputs to export parameter names and policy ARN. | ||
| */ | ||
| export class SsmParametersConstruct extends Construct { | ||
| public readonly parameters: Record<string, StringParameter> | ||
| public readonly readParametersPolicy: ManagedPolicy | ||
|
|
||
| /** | ||
| * Creates SSM String parameters, a managed read policy, and CloudFormation outputs. | ||
| * | ||
| * @param scope CDK construct scope. | ||
| * @param id Unique construct identifier. | ||
| * @param props Configuration for parameter names, values, and exported outputs. | ||
| * @throws {Error} Throws when no parameter definitions are provided. | ||
| * @throws {Error} Throws when duplicate parameter IDs or parameter names are detected. | ||
| */ | ||
| public constructor(scope: Construct, id: string, props: SsmParametersConstructProps) { | ||
| super(scope, id) | ||
|
|
||
| const { | ||
| namePrefix: stackName, | ||
| parameters, | ||
| readPolicyExportSuffix, | ||
| readPolicyDescription = "Allows reading SSM parameters", | ||
| readPolicyOutputDescription = "Access to the parameters used by the integration" | ||
|
wildjames marked this conversation as resolved.
|
||
| } = props | ||
|
|
||
| if (parameters.length === 0) { | ||
| throw new Error("SsmParametersConstruct requires at least one parameter definition") | ||
| } | ||
|
|
||
| const createdParameters: Record<string, StringParameter> = {} | ||
|
|
||
| const seenIds = new Set<string>() | ||
| const seenNames = new Set<string>() | ||
|
|
||
| for (const parameter of parameters) { | ||
| const parameterId = `${parameter.id}Parameter` | ||
| if (seenIds.has(parameterId)) { | ||
| throw new Error(`Duplicate parameter id detected: ${parameter.id}.`) | ||
| } | ||
| seenIds.add(parameterId) | ||
|
|
||
| const parameterName = `${stackName}-${parameter.nameSuffix}` | ||
| if (seenNames.has(parameterName)) { | ||
| throw new Error(`Duplicate parameter name detected: ${parameterName}.`) | ||
| } | ||
| seenNames.add(parameterName) | ||
|
|
||
| const ssmParameter = new StringParameter(this, parameterId, { | ||
| parameterName, | ||
| description: parameter.description, | ||
| stringValue: parameter.value | ||
| }) | ||
|
|
||
| createdParameters[parameter.id] = ssmParameter | ||
|
|
||
| new CfnOutput(this, `${parameter.id}ParameterNameOutput`, { | ||
| description: parameter.outputDescription ?? parameter.description, | ||
| value: ssmParameter.parameterName, | ||
| exportName: `${stackName}-${parameter.outputExportSuffix ?? parameter.nameSuffix}` | ||
| }) | ||
| } | ||
|
wildjames marked this conversation as resolved.
|
||
|
|
||
| const readParametersPolicy = new ManagedPolicy(this, "GetParametersPolicy", { | ||
| description: readPolicyDescription, | ||
| statements: [ | ||
| new PolicyStatement({ | ||
| effect: Effect.ALLOW, | ||
| actions: ["ssm:GetParameter", "ssm:GetParameters"], | ||
| resources: Object.values(createdParameters).map((parameter) => parameter.parameterArn) | ||
| }) | ||
| ] | ||
| }) | ||
|
|
||
| new CfnOutput(this, "ReadParametersPolicyOutput", { | ||
| description: readPolicyOutputDescription, | ||
| value: readParametersPolicy.managedPolicyArn, | ||
| exportName: `${stackName}-${readPolicyExportSuffix}` | ||
| }) | ||
|
|
||
| this.parameters = createdParameters | ||
| this.readParametersPolicy = readParametersPolicy | ||
| } | ||
| } | ||
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the idiomatic way to do this would be to use an options object, but that would break downstream things and for this I don't want to mess about with that if we can avoid it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicitly initialising to undefined feels a bit excessive.
There a couple of these