feat(synthetics): add artifactS3Encryption property to the Canary Construct.#30197
Conversation
| this._connections = new ec2.Connections({}); | ||
| } | ||
|
|
||
| if (props.runtime.family !== RuntimeFamily.NODEJS && props.artifactS3Encryption) { |
There was a problem hiding this comment.
Artifact encryption functionality is available only for canaries that use Synthetics runtime version syn-nodejs-puppeteer-3.3 or later.
However, versions prior to 3.3 are deprecated and can no longer be configured, which is why I implemented it this way.
There was a problem hiding this comment.
Makes sense 👍 Can you please add a short comment about it before the check?
There was a problem hiding this comment.
Thanks. I've added a comment.
lpizzinidev
left a comment
There was a problem hiding this comment.
Thanks 👍 Left some comments for some initial adjustments
| * | ||
| * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_artifact_encryption.html | ||
| */ | ||
| readonly artifactS3Encryption?: ArtifactS3Encryption; |
There was a problem hiding this comment.
| readonly artifactS3Encryption?: ArtifactS3Encryption; | |
| readonly artifactS3EncryptionMode?: ArtifactsEncryptionMode; | |
| /** | |
| * The KMS key used to encrypt the data. | |
| * | |
| * @default - A KMS key is automatically created if `artifactS3EncryptionMode` is set to `SSE_KMS`. Otherwise, no key is generated. | |
| */ | |
| readonly artifactS3EncryptionKey?: kms.IKey; |
What about keeping this flat? (guidelines)
There was a problem hiding this comment.
Thank you. Canary Construct is implemented to flatten other properties as well, so I agree that it would be better to flatten it in this case as you suggested. I will modify it to make it flat.
There was a problem hiding this comment.
I've changed it to flat.
| this._connections = new ec2.Connections({}); | ||
| } | ||
|
|
||
| if (props.runtime.family !== RuntimeFamily.NODEJS && props.artifactS3Encryption) { |
There was a problem hiding this comment.
Makes sense 👍 Can you please add a short comment about it before the check?
| this._connections = new ec2.Connections({}); | ||
| } | ||
|
|
||
| if (!cdk.Token.isUnresolved(props.artifactS3EncryptionMode) && |
There was a problem hiding this comment.
I refactored the creation of artifactConfig into createArtifactConfig.
However, since kmsKey needs to be set as a property, I made it so that checking and setting are done here.
Please provide your opinion if there is a better way to do this.
There was a problem hiding this comment.
I like the approach, just a couple of adjustments:
- Why not move all validations inside the method?
- No need to declare the
public readonly encryptionKey?: kms.IKey;variable - Watch out for the typo in the function name
Suggestion:
private createArtifactConfig(props: CanaryProps): CfnCanary.ArtifactConfigProperty | undefined {
if (!props.artifactS3EncryptionMode) {
return undefined;
}
const isNodeRuntime = !cdk.Token.isUnresolved(props.runtime) && props.runtime.family === RuntimeFamily.NODEJS;
const isArtifactS3EncryptionModeDefined = !cdk.Token.isUnresolved(props.artifactS3EncryptionMode) && props.artifactS3EncryptionMode;
const isArtifactS3KmsKeyDefined = !cdk.Token.isUnresolved(props.artifactS3KmsKey) && props.artifactS3KmsKey;
if (isArtifactS3EncryptionModeDefined &&
props.artifactS3EncryptionMode !== ArtifactsEncryptionMode.KMS &&
isArtifactS3KmsKeyDefined
) {
throw new Error('A customer-managed KMS key was provided, but the encryption mode is not set to SSE-KMS.');
}
// Only check runtime family is nodejs because versions prior to syn-nodejs-puppeteer-3.3 are deprecated and can no longer be configured.
if (!isNodeRuntime && isArtifactS3EncryptionModeDefined) {
throw new Error(`Artifact encryption is only supported for canaries that use Synthetics runtime version syn-nodejs-puppeteer-3.3 or later, got ${props.runtime.name}.`);
}
let encryptionKey: kms.IKey | undefined;
if (props.artifactS3EncryptionMode === ArtifactsEncryptionMode.KMS) {
// Kms Key is set or generated for using `createArtifactConfig`
encryptionKey = props.artifactS3KmsKey ?? new kms.Key(this, 'Key', { description: `Created by ${this.node.path}` });
}
encryptionKey?.grantEncryptDecrypt(this.role);
return {
s3Encryption: {
encryptionMode: props.artifactS3EncryptionMode,
artifactS3KmsKeyArn: encryptionKey?.keyArn,
},
};
}|
Thank you for the review. I incorporated the comments and refactored. |
lpizzinidev
left a comment
There was a problem hiding this comment.
Thanks 👍 Left comments for some final adjustments
| this._connections = new ec2.Connections({}); | ||
| } | ||
|
|
||
| if (!cdk.Token.isUnresolved(props.artifactS3EncryptionMode) && |
There was a problem hiding this comment.
I like the approach, just a couple of adjustments:
- Why not move all validations inside the method?
- No need to declare the
public readonly encryptionKey?: kms.IKey;variable - Watch out for the typo in the function name
Suggestion:
private createArtifactConfig(props: CanaryProps): CfnCanary.ArtifactConfigProperty | undefined {
if (!props.artifactS3EncryptionMode) {
return undefined;
}
const isNodeRuntime = !cdk.Token.isUnresolved(props.runtime) && props.runtime.family === RuntimeFamily.NODEJS;
const isArtifactS3EncryptionModeDefined = !cdk.Token.isUnresolved(props.artifactS3EncryptionMode) && props.artifactS3EncryptionMode;
const isArtifactS3KmsKeyDefined = !cdk.Token.isUnresolved(props.artifactS3KmsKey) && props.artifactS3KmsKey;
if (isArtifactS3EncryptionModeDefined &&
props.artifactS3EncryptionMode !== ArtifactsEncryptionMode.KMS &&
isArtifactS3KmsKeyDefined
) {
throw new Error('A customer-managed KMS key was provided, but the encryption mode is not set to SSE-KMS.');
}
// Only check runtime family is nodejs because versions prior to syn-nodejs-puppeteer-3.3 are deprecated and can no longer be configured.
if (!isNodeRuntime && isArtifactS3EncryptionModeDefined) {
throw new Error(`Artifact encryption is only supported for canaries that use Synthetics runtime version syn-nodejs-puppeteer-3.3 or later, got ${props.runtime.name}.`);
}
let encryptionKey: kms.IKey | undefined;
if (props.artifactS3EncryptionMode === ArtifactsEncryptionMode.KMS) {
// Kms Key is set or generated for using `createArtifactConfig`
encryptionKey = props.artifactS3KmsKey ?? new kms.Key(this, 'Key', { description: `Created by ${this.node.path}` });
}
encryptionKey?.grantEncryptDecrypt(this.role);
return {
s3Encryption: {
encryptionMode: props.artifactS3EncryptionMode,
artifactS3KmsKeyArn: encryptionKey?.keyArn,
},
};
}6f06849 to
5f26026
Compare
|
@lpizzinidev |
lpizzinidev
left a comment
There was a problem hiding this comment.
Thanks 👍
Not sure about the failing build. It seems like an issue with automation scripts:
error /home/runner/work/aws-cdk/aws-cdk/node_modules/@lerna/create/node_modules/nx, /home/runner/work/aws-cdk/aws-cdk/node_modules/@nx/devkit/node_modules/nx, /home/runner/work/aws-cdk/aws-cdk/node_modules/lerna/node_modules/nx: Command failed.
ffa5818 to
4ca916c
Compare
|
Because of the nature of the encryption key and permission granting changes, I'm adding the security review label to this as well. We'll review the PR internally with security and let you know if there's any extra changes needed. |
4aaf084 to
f914da9
Compare
f914da9 to
fa72ee2
Compare
Leo10Gama
left a comment
There was a problem hiding this comment.
Thanks for addressing the changes! Just a few more comments about some of the recent changes.
| isArtifactS3EncryptionModeDefined && | ||
| props.artifactS3EncryptionMode !== ArtifactsEncryptionMode.KMS && | ||
| isArtifactS3KmsKeyDefined | ||
| props.artifactS3EncryptionMode === ArtifactsEncryptionMode.S3_MANAGED && | ||
| props.artifactS3KmsKey |
There was a problem hiding this comment.
I can see we're no longer checking if these props are tokens. Is it possible for users to provide them as tokens? I don't think it would change much of the logic here, but if they can be tokens, we ought to have unit tests for them.
There was a problem hiding this comment.
As I understand it, these are not expected to become tokens. Therefore, the token check is unnecessary, so I removed it.
Pull request has been modified.
Leo10Gama
left a comment
There was a problem hiding this comment.
LGTM, thanks for the contribution!
|
@Mergifyio update |
❌ Mergify doesn't have permission to updateDetailsFor security reasons, Mergify can't update this pull request. Try updating locally. |
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Pull request has been modified.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
|
Comments on closed issues and PRs are hard for our team to see. |
Issue # (if applicable)
Closes #30190.
Reason for this change
To select encryption options.
Description of changes
Add
artifactS3Encryptionproperty to the Canary Construct.Description of how you validated changes
Add unit tests and integ tests.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license