Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(efs): graduate to stable 馃殌 #14033

Merged
merged 16 commits into from Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 2 additions & 12 deletions packages/@aws-cdk/aws-efs/README.md
Expand Up @@ -5,17 +5,7 @@

![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)

> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.
>
> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib

![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)

> The APIs of higher level constructs in this module are experimental and under active development.
> They are subject to non-backward compatible changes or removal in any future version. These are
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
> announced in the release notes. This means that while you may use them, you may need to update
> your source code when upgrading to a newer version of this package.
![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)

---

Expand Down Expand Up @@ -44,10 +34,10 @@ Access (IA) storage class.
```ts
const fileSystem = new efs.FileSystem(this, 'MyEfsFileSystem', {
vpc: new ec2.Vpc(this, 'VPC'),
encrypted: true, // file system is not encrypted by default
lifecyclePolicy: efs.LifecyclePolicy.AFTER_14_DAYS, // files are not transitioned to infrequent access (IA) storage by default
performanceMode: efs.PerformanceMode.GENERAL_PURPOSE, // default
});

```

鈿狅笍 An Amazon EFS file system's performance mode can't be changed after the file system has been created.
Expand Down
14 changes: 12 additions & 2 deletions packages/@aws-cdk/aws-efs/lib/efs-file-system.ts
@@ -1,6 +1,10 @@
import * as ec2 from '@aws-cdk/aws-ec2';
import * as kms from '@aws-cdk/aws-kms';
import { ConcreteDependable, IDependable, IResource, RemovalPolicy, Resource, Size, Tags } from '@aws-cdk/core';
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports
import { FeatureFlags } from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { AccessPoint, AccessPointOptions } from './access-point';
import { CfnFileSystem, CfnMountTarget } from './efs.generated';
Expand Down Expand Up @@ -122,7 +126,8 @@ export interface FileSystemProps {
/**
* Defines if the data at rest in the file system is encrypted or not.
*
* @default false
* @default - If your application has the '@aws-cdk/aws-efs:defaultEncryptionAtRest' feature flag set, the default is true, otherwise, the default is false.
* @link https://docs.aws.amazon.com/cdk/latest/guide/featureflags.html
*/
readonly encrypted?: boolean;

Expand Down Expand Up @@ -249,8 +254,13 @@ export class FileSystem extends Resource implements IFileSystem {
throw new Error('Property provisionedThroughputPerSecond is required when throughputMode is PROVISIONED');
}

// we explictly use 'undefined' to represent 'false' to maintain backwards compatibility since
// its considered an actual change in CloudFormations eyes, even though they have the same meaning.
const encrypted = props.encrypted ?? (FeatureFlags.of(this).isEnabled(
cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST) ? true : undefined);

const filesystem = new CfnFileSystem(this, 'Resource', {
encrypted: props.encrypted,
encrypted: encrypted,
kmsKeyId: props.kmsKey?.keyArn,
lifecyclePolicies: (props.lifecyclePolicy ? [{ transitionToIa: props.lifecyclePolicy }] : undefined),
performanceMode: props.performanceMode,
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-efs/package.json
Expand Up @@ -103,8 +103,8 @@
"resource-attribute:@aws-cdk/aws-efs.FileSystem.fileSystemArn"
]
},
"stability": "experimental",
"maturity": "experimental",
"stability": "stable",
"maturity": "stable",
"awscdkio": {
"announce": false
},
Expand Down
50 changes: 49 additions & 1 deletion packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts
@@ -1,7 +1,8 @@
import { expect as expectCDK, haveResource, ResourcePart, countResources } from '@aws-cdk/assert-internal';
import { ABSENT, expect as expectCDK, haveResource, ResourcePart, countResources } from '@aws-cdk/assert-internal';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as kms from '@aws-cdk/aws-kms';
import { RemovalPolicy, Size, Stack, Tags } from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
import { FileSystem, LifecyclePolicy, PerformanceMode, ThroughputMode } from '../lib';

let stack = new Stack();
Expand All @@ -12,6 +13,53 @@ beforeEach(() => {
vpc = new ec2.Vpc(stack, 'VPC');
});

test(`when ${cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST} is enabled, encryption is enabled by default`, () => {

const customStack = new Stack();
customStack.node.setContext(cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST, true);

const customVpc = new ec2.Vpc(customStack, 'VPC');
new FileSystem(customVpc, 'EfsFileSystem', {
vpc: customVpc,
});

expectCDK(customStack).to(haveResource('AWS::EFS::FileSystem', {
Encrypted: true,
}));

});

test(`when ${cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST} is disabled, encryption is disabled by default`, () => {

const customStack = new Stack();
customStack.node.setContext(cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST, false);

const customVpc = new ec2.Vpc(customStack, 'VPC');
new FileSystem(customVpc, 'EfsFileSystem', {
vpc: customVpc,
});

expectCDK(customStack).to(haveResource('AWS::EFS::FileSystem', {
Encrypted: ABSENT,
}));

});

test(`when ${cxapi.EFS_DEFAULT_ENCRYPTION_AT_REST} is missing, encryption is disabled by default`, () => {

const customStack = new Stack();

const customVpc = new ec2.Vpc(customStack, 'VPC');
new FileSystem(customVpc, 'EfsFileSystem', {
vpc: customVpc,
});

expectCDK(customStack).to(haveResource('AWS::EFS::FileSystem', {
Encrypted: ABSENT,
}));

});

test('default file system is created correctly', () => {
// WHEN
new FileSystem(stack, 'EfsFileSystem', {
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-efs/test/integ.efs.expected.json
Expand Up @@ -453,6 +453,7 @@
"FileSystem8A8E25C0": {
"Type": "AWS::EFS::FileSystem",
"Properties": {
"Encrypted": true,
iliapolo marked this conversation as resolved.
Show resolved Hide resolved
"FileSystemTags": [
{
"Key": "Name",
Expand Down
Expand Up @@ -453,6 +453,7 @@
"Efs9E8BF36B": {
"Type": "AWS::EFS::FileSystem",
"Properties": {
"Encrypted": true,
"FileSystemTags": [
{
"Key": "Name",
Expand Down Expand Up @@ -738,17 +739,14 @@
"Code": {
"ZipFile": "\nimport json\nimport os\nimport string\nimport random\nimport datetime\n\nMSG_FILE_PATH = '/mnt/msg/content'\n\ndef randomString(stringLength=10):\n letters = string.ascii_lowercase\n return ''.join(random.choice(letters) for i in range(stringLength))\n\ndef lambda_handler(event, context):\n with open(MSG_FILE_PATH, 'a') as f:\n f.write(f\"{datetime.datetime.utcnow():%Y-%m-%d-%H:%M:%S} \" + randomString(5) + ' ')\n\n file = open(MSG_FILE_PATH, \"r\")\n file_content = file.read()\n file.close()\n\n return {\n 'statusCode': 200,\n 'body': str(file_content)\n }\n"
},
"Handler": "index.lambda_handler",
"Role": {
"Fn::GetAtt": [
"MyLambdaServiceRole4539ECB6",
"Arn"
]
},
"Runtime": "python3.7",
"FileSystemConfigs": [
{
"LocalMountPath": "/mnt/msg",
"Arn": {
"Fn::Join": [
"",
Expand All @@ -771,9 +769,12 @@
}
]
]
}
},
"LocalMountPath": "/mnt/msg"
}
],
"Handler": "index.lambda_handler",
"Runtime": "python3.7",
"VpcConfig": {
"SecurityGroupIds": [
{
Expand Down Expand Up @@ -983,17 +984,14 @@
"Code": {
"ZipFile": "\nimport json\nimport os\nimport string\nimport random\nimport datetime\n\nMSG_FILE_PATH = '/mnt/msg/content'\n\ndef randomString(stringLength=10):\n letters = string.ascii_lowercase\n return ''.join(random.choice(letters) for i in range(stringLength))\n\ndef lambda_handler(event, context):\n with open(MSG_FILE_PATH, 'a') as f:\n f.write(f\"{datetime.datetime.utcnow():%Y-%m-%d-%H:%M:%S} \" + randomString(5) + ' ')\n\n file = open(MSG_FILE_PATH, \"r\")\n file_content = file.read()\n file.close()\n\n return {\n 'statusCode': 200,\n 'body': str(file_content)\n }\n"
},
"Handler": "index.lambda_handler",
"Role": {
"Fn::GetAtt": [
"MyLambda2ServiceRoleD09B370C",
"Arn"
]
},
"Runtime": "python3.7",
"FileSystemConfigs": [
{
"LocalMountPath": "/mnt/msg",
"Arn": {
"Fn::Join": [
"",
Expand All @@ -1016,9 +1014,12 @@
}
]
]
}
},
"LocalMountPath": "/mnt/msg"
}
],
"Handler": "index.lambda_handler",
"Runtime": "python3.7",
"VpcConfig": {
"SecurityGroupIds": [
{
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/cx-api/lib/features.ts
Expand Up @@ -135,6 +135,12 @@ export const RDS_LOWERCASE_DB_IDENTIFIER = '@aws-cdk/aws-rds:lowercaseDbIdentifi
*/
export const APIGATEWAY_USAGEPLANKEY_ORDERINSENSITIVE_ID = '@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId';

/**
* Enable this feature flag to have elastic file systems encrypted at rest by default.
*
* Encryption can also be configured explicitly using the `encrypted` property.
*/
export const EFS_DEFAULT_ENCRYPTION_AT_REST = '@aws-cdk/aws-efs:defaultEncryptionAtRest';
/**
* This map includes context keys and values for feature flags that enable
* capabilities "from the future", which we could not introduce as the default
Expand All @@ -159,6 +165,7 @@ export const FUTURE_FLAGS: { [key: string]: any } = {
[S3_GRANT_WRITE_WITHOUT_ACL]: true,
[ECS_REMOVE_DEFAULT_DESIRED_COUNT]: true,
[RDS_LOWERCASE_DB_IDENTIFIER]: true,
[EFS_DEFAULT_ENCRYPTION_AT_REST]: true,

// We will advertise this flag when the feature is complete
// [NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: 'true',
Expand Down Expand Up @@ -187,6 +194,7 @@ const FUTURE_FLAGS_DEFAULTS: { [key: string]: boolean } = {
[S3_GRANT_WRITE_WITHOUT_ACL]: false,
[ECS_REMOVE_DEFAULT_DESIRED_COUNT]: false,
[RDS_LOWERCASE_DB_IDENTIFIER]: false,
[EFS_DEFAULT_ENCRYPTION_AT_REST]: false,
};

export function futureFlagDefault(flag: string): boolean {
Expand Down