Skip to content

Commit 0b35418

Browse files
authored
feat(aws-fargate-dynamodb): create new construct (#633)
* created README for aws-fargate-dynamodb * created aws-fargate-dynamodb construct * revised buildDynamoDBTable helper function to support old/new constructs * updated prop variable name * added error and endpoint checking tests * checked for table permissions * checked props in input-validation * moved table interface and object check to buildDynamoDBTable function * created prop check function in dynamo helper file
1 parent 2e27bf9 commit 0b35418

17 files changed

+3736
-13
lines changed

source/patterns/@aws-solutions-constructs/aws-apigateway-dynamodb/lib/index.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,13 @@ export class ApiGatewayToDynamoDB extends Construct {
131131
partitionKeyName = getPartitionKeyNameFromTable(props.existingTableObj);
132132
}
133133

134+
// Since we are only invoking this function with an existing Table or tableProps,
135+
// (not a table interface), we know that the implementation will always return
136+
// a Table object and we can safely cast away the optional aspect of the type.
134137
this.dynamoTable = defaults.buildDynamoDBTable(this, {
135138
existingTableObj: props.existingTableObj,
136-
dynamoTableProps,
137-
});
139+
dynamoTableProps: props.dynamoTableProps
140+
})[1] as dynamodb.Table;
138141

139142
// Setup the API Gateway
140143
[this.apiGateway, this.apiGatewayCloudWatchRole, this.apiGatewayLogGroup] = defaults.GlobalRestApi(this,
@@ -170,7 +173,7 @@ export class ApiGatewayToDynamoDB extends Construct {
170173
readRequestTemplate = props.readRequestTemplate;
171174
} else {
172175
readRequestTemplate =
173-
`{ \
176+
`{ \
174177
"TableName": "${this.dynamoTable.tableName}", \
175178
"KeyConditionExpression": "${partitionKeyName} = :v1", \
176179
"ExpressionAttributeValues": { \
@@ -212,7 +215,7 @@ export class ApiGatewayToDynamoDB extends Construct {
212215
deleteRequestTemplate = props.deleteRequestTemplate;
213216
} else {
214217
deleteRequestTemplate =
215-
`{ \
218+
`{ \
216219
"TableName": "${this.dynamoTable.tableName}", \
217220
"Key": { \
218221
"${partitionKeyName}": { \
@@ -240,7 +243,7 @@ export class ApiGatewayToDynamoDB extends Construct {
240243
resources: [
241244
this.dynamoTable.tableArn
242245
],
243-
actions: [ `${action}` ]
246+
actions: [`${action}`]
244247
}));
245248
}
246249
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lib/*.js
2+
test/*.js
3+
*.d.ts
4+
coverage
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
lib/*.js
2+
test/*.js
3+
*.js.map
4+
*.d.ts
5+
node_modules
6+
*.generated.ts
7+
dist
8+
.jsii
9+
10+
.LAST_BUILD
11+
.nyc_output
12+
coverage
13+
.nycrc
14+
.LAST_PACKAGE
15+
*.snk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Exclude typescript source and config
2+
*.ts
3+
tsconfig.json
4+
coverage
5+
.nyc_output
6+
*.tgz
7+
*.snk
8+
*.tsbuildinfo
9+
10+
# Include javascript files and typescript declarations
11+
!*.js
12+
!*.d.ts
13+
14+
# Exclude jsii outdir
15+
dist
16+
17+
# Include .jsii
18+
!.jsii
19+
20+
# Include .jsii
21+
!.jsii
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# aws-fargate-dynamodb module
2+
<!--BEGIN STABILITY BANNER-->
3+
4+
---
5+
6+
![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge)
7+
8+
> All classes are under active development and subject to non-backward compatible changes or removal in any
9+
> future version. These are not subject to the [Semantic Versioning](https://semver.org/) model.
10+
> 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.
11+
12+
---
13+
<!--END STABILITY BANNER-->
14+
15+
| **Reference Documentation**:| <span style="font-weight: normal">https://docs.aws.amazon.com/solutions/latest/constructs/</span>|
16+
|:-------------|:-------------|
17+
<div style="height:8px"></div>
18+
19+
| **Language** | **Package** |
20+
|:-------------|-----------------|
21+
|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_fargate_dynamodb`|
22+
|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-fargate-dynamodb`|
23+
|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.fargatedynamodb`|
24+
25+
This AWS Solutions Construct implements an AWS Fargate service that can write/read to an Amazon DynamoDB table
26+
27+
Here is a minimal deployable pattern definition:
28+
29+
Typescript
30+
``` typescript
31+
import { Construct } from 'constructs';
32+
import { Stack, StackProps } from 'aws-cdk-lib';
33+
import { FargateToDynamoDB, FargateToDynamoDBProps } from '@aws-solutions-constructs/aws-fargate-dynamodb';
34+
35+
const constructProps: FargateToDynamoDBProps = {
36+
publicApi: true,
37+
ecrRepositoryArn: "arn:aws:ecr:us-east-1:123456789012:repository/your-ecr-repo",
38+
};
39+
40+
new FargateToDynamoDB(stack, 'test-construct', constructProps);
41+
```
42+
43+
Python
44+
``` python
45+
from aws_solutions_constructs.aws_fargate_dynamodb import FargateToDynamoDB, FargateToDynamoDBProps
46+
from aws_cdk import (
47+
Stack
48+
)
49+
from constructs import Construct
50+
51+
FargateToDynamoDB(self, 'test_construct',
52+
public_api=True,
53+
ecr_repository_arn="arn:aws:ecr:us-east-1:123456789012:repository/your-ecr-repo")
54+
```
55+
56+
Java
57+
``` java
58+
import software.constructs.Construct;
59+
60+
import software.amazon.awscdk.Stack;
61+
import software.amazon.awscdk.StackProps;
62+
import software.amazon.awsconstructs.services.fargatedynamodb.*;
63+
64+
new FargateToDynamoDB(this, "test-construct", new FargateToDynamoDBProps.Builder()
65+
.publicApi(true)
66+
.ecrRepositoryArn("arn:aws:ecr:us-east-1:123456789012:repository/your-ecr-repo")
67+
.build());
68+
```
69+
70+
## Pattern Construct Props
71+
72+
| **Name** | **Type** | **Description** |
73+
|:-------------|:----------------|-----------------|
74+
| publicApi | `boolean` | Whether the construct is deploying a private or public API. This has implications for the VPC. |
75+
| vpcProps? | [`ec2.VpcProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.VpcProps.html) | Optional custom properties for a VPC the construct will create. This VPC will be used by any Private Hosted Zone the construct creates (that's why loadBalancerProps and privateHostedZoneProps can't include a VPC). Providing both this and existingVpc is an error. |
76+
| existingVpc? | [`ec2.IVpc`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.IVpc.html) | An existing VPC in which to deploy the construct. Providing both this and vpcProps is an error. If the client provides an existing load balancer and/or existing Private Hosted Zone, those constructs must exist in this VPC. |
77+
| clusterProps? | [`ecs.ClusterProps`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.ClusterProps.html) | Optional properties to create a new ECS cluster. To provide an existing cluster, use the cluster attribute of fargateServiceProps. |
78+
| ecrRepositoryArn? | `string` | The arn of an ECR Repository containing the image to use to generate the containers. Either this or the image property of containerDefinitionProps must be provided. format: arn:aws:ecr:*region*:*account number*:repository/*Repository Name* |
79+
| ecrImageVersion? | `string` | The version of the image to use from the repository. Defaults to 'Latest' |
80+
| containerDefinitionProps? | [`ecs.ContainerDefinitionProps \| any`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.ContainerDefinitionProps.html) | Optional props to define the container created for the Fargate Service (defaults found in fargate-defaults.ts) |
81+
| fargateTaskDefinitionProps? | [`ecs.FargateTaskDefinitionProps \| any`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.FargateTaskDefinitionProps.html) | Optional props to define the Fargate Task Definition for this construct (defaults found in fargate-defaults.ts) |
82+
| fargateServiceProps? | [`ecs.FargateServiceProps \| any`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.FargateServiceProps.html) | Optional values to override default Fargate Task definition properties (fargate-defaults.ts). The construct will default to launching the service is the most isolated subnets available (precedence: Isolated, Private and Public). Override those and other defaults here. |
83+
| existingFargateServiceObject? | [`ecs.FargateService`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.FargateService.html) | A Fargate Service already instantiated (probably by another Solutions Construct). If this is specified, then no props defining a new service can be provided, including: ecrImageVersion, containerDefinitionProps, fargateTaskDefinitionProps, ecrRepositoryArn, fargateServiceProps, clusterProps |
84+
| existingContainerDefinitionObject? | [`ecs.ContainerDefinition`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.ContainerDefinition.html) | A container definition already instantiated as part of a Fargate service. This must be the container in the existingFargateServiceObject |
85+
| dynamoTableProps? | [`dynamodb.TableProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-dynamodb.TableProps.html)|Optional user provided props to override the default props for DynamoDB Table.|
86+
|existingTableInterface?|[`dynamodb.ITable`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-dynamodb.ITable.html)|Existing instance of DynamoDB table object or interface, providing both this and `dynamoTableProps` will cause an error.|
87+
| tablePermissions? |`string`|Optional table permissions to grant to the Fargate service. One of the following may be specified: `All`, `Read`, `ReadWrite`, `Write`.|
88+
|tableArnEnvironmentVariableName?|`string`|Optional Name for the DynamoDB table arn environment variable set for the container.|
89+
|tableEnvironmentVariableName?|`string`|Optional Name for the DynamoDB table name environment variable set for the container.|
90+
91+
## Pattern Properties
92+
93+
| **Name** | **Type** | **Description** |
94+
|:-------------|:----------------|-----------------|
95+
| vpc | [`ec2.IVpc`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.IVpc.html) | The VPC used by the construct (whether created by the construct or provided by the client) |
96+
| service | [`ecs.FargateService`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.FargateService.html) | The AWS Fargate service used by this construct (whether created by this construct or passed to this construct at initialization) |
97+
| container | [`ecs.ContainerDefinition`](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.ContainerDefinition.html) | The container associated with the AWS Fargate service in the service property. |
98+
|dynamoTableInterface|[`dynamodb.ITable`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-dynamodb.ITable.html)|Returns an instance of `dynamodb.ITable` created by the construct or the interface provided in existingTableInterface.|
99+
|dynamoTable?|[`dynamodb.Table`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-dynamodb.Table.html)|Returns an instance of `dynamodb.Table` created by the construct. IMPORTANT: If existingTableInterface was provided in Pattern Construct Props, this property will be `undefined`.|
100+
101+
## Default settings
102+
103+
Out of the box implementation of the Construct without any override will set the following defaults:
104+
105+
### AWS Fargate Service
106+
* Sets up an AWS Fargate service
107+
* Uses the existing service if provided
108+
* Creates a new service if none provided.
109+
* Service will run in isolated subnets if available, then private subnets if available and finally public subnets
110+
* Adds environment variables to the container with the ARN and Name of the DynamoDB table
111+
* Add permissions to the container IAM role allowing it to publish to the DynamoDB table
112+
113+
### Amazon DynamoDB Table
114+
* Sets up an Amazon DynamoDB table
115+
* Uses an existing table if one is provided, otherwise creates a new one
116+
* Adds an Interface Endpoint to the VPC for DynamoDB (the service by default runs in Isolated or Private subnets)
117+
118+
## Architecture
119+
![Architecture Diagram](architecture.png)
120+
121+
***
122+
&copy; Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading

0 commit comments

Comments
 (0)