@btc-embedded/cdk-extensions 0.14.12 → 0.14.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +4 -4
- package/CHANGELOG.md +17 -0
- package/README.md +32 -1
- package/lib/constructs/EventPipe.js +1 -1
- package/lib/constructs/S3Bucket.js +1 -1
- package/lib/constructs/SecureRestApi.js +1 -1
- package/lib/constructs/SecureRestApiV2.js +1 -1
- package/lib/extensions/ApiGatewayExtension.js +1 -1
- package/lib/extensions/ApplicationLoadBalancerExtension.js +1 -1
- package/lib/extensions/ApplicationLoadBalancerExtensionV2.js +1 -1
- package/lib/extensions/CloudMapExtension.js +1 -1
- package/lib/extensions/DeactivatableServiceExtension.js +1 -1
- package/lib/extensions/DocumentDbAccessExtension.js +1 -1
- package/lib/extensions/DomainEventMessagingExtension.js +1 -1
- package/lib/extensions/EfsMountExtension.js +1 -1
- package/lib/extensions/ExtraContainerExtension.js +1 -1
- package/lib/extensions/HTTPApiExtension.js +1 -1
- package/lib/extensions/LogExtension.js +1 -1
- package/lib/extensions/ModifyContainerDefinitionExtension.js +1 -1
- package/lib/extensions/ModifyTaskDefinitionExtension.js +1 -1
- package/lib/extensions/OpenTelemetryExtension.js +1 -1
- package/lib/extensions/PostgresDbAccessExtension.js +1 -1
- package/lib/extensions/SharedVolumeExtension.js +1 -1
- package/lib/extensions/TcpKeepAliveExtension.js +1 -1
- package/lib/platform/ApiGateway.js +1 -1
- package/lib/platform/ApiGatewayV2.js +2 -2
- package/lib/platform/ApplicationLoadBalancer.js +1 -1
- package/lib/platform/ApplicationLoadBalancerV2.js +2 -2
- package/lib/platform/BTCLogGroup.js +1 -1
- package/lib/platform/CognitoUserPool.js +2 -2
- package/lib/platform/DefaultUserPoolClients.js +1 -1
- package/lib/platform/DocumentDB.js +2 -2
- package/lib/platform/PrivateDnsNamespace.js +1 -1
- package/lib/platform/ResourceServer.js +1 -1
- package/lib/platform/Vpc.js +1 -1
- package/lib/utils/StackParameter.js +1 -1
- package/package.json +2 -2
- package/.backstage/catalog-info.yaml +0 -19
- package/.gitlab-ci.yml +0 -65
- package/docs/RFC001-api-gateway.md +0 -77
- package/docs/RFC002-developer-stacks.md +0 -268
- package/docs/RFC003-referencing-platform-components.md +0 -125
- package/docs/adrs/0001-use-adrs.md +0 -36
- package/docs/index.md +0 -20
- package/mkdocs.yml +0 -8
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
# Support for Developer Stacks
|
|
2
|
-
|
|
3
|
-
## Objective
|
|
4
|
-
|
|
5
|
-
This document describes how to provide custom stacks for developers that allow to deactivate components in order to replace them with local services for testing and debugging.
|
|
6
|
-
|
|
7
|
-
## Target Projects
|
|
8
|
-
|
|
9
|
-
The current implementation is targeting the EP 3.x project, i.e. the suggestions are based on the projects' needs. However, the design is intended to be used for future projects and extended to meet their requirements.
|
|
10
|
-
|
|
11
|
-
## Prerequisites
|
|
12
|
-
|
|
13
|
-
The architecture of the stack to be used has to be designed in such a way that single components can be used locally. This can be achieved by providing loose coupling between the components, e.g. by communicating via SQS or databases. The design is not part of this document, but without it, it is not possible to deactivate components and replace them with local ones.
|
|
14
|
-
|
|
15
|
-
## Problem Statement
|
|
16
|
-
|
|
17
|
-
There are two problems that we want to solve with this proposal.
|
|
18
|
-
|
|
19
|
-
### Separate Developer Stacks
|
|
20
|
-
|
|
21
|
-
The developers do not want to use the default stack deployed to the development stage, as messages and other data may be consumed by components and services deployed within the stage or by other developers. This causes unpredictable behavior and thus makes testing and debugging components hard or even impossible.
|
|
22
|
-
|
|
23
|
-
By allowing each developer to deploy a separate stage, this can be circumvented, as all data is used only by a single developer and the default development stage is not affected.
|
|
24
|
-
|
|
25
|
-
### Partial Stack Deployments
|
|
26
|
-
|
|
27
|
-
In shall be possible to test and debug single components of a stack. This is not easily possible, when the component is deployed to the cloud. Thus, a developer wants to execute and debug a single component locally, while still using the cloud environment and all other components.
|
|
28
|
-
|
|
29
|
-
By allowing to deactivate components in the stack, we can enable the developers to perform the local tests.
|
|
30
|
-
|
|
31
|
-
## Requirements
|
|
32
|
-
|
|
33
|
-
- It should be prevented to have configuration files for each developer, as managing and extending the files, especially if the schema has changed, may cause additional effort.
|
|
34
|
-
- It should be prevented that excessive changes within the existing stack implementations have to be performed. Instead, the `cdk-extensions` should be adjusted to allow generic configurability.
|
|
35
|
-
- Storage space should not be used excessively and thus files in a bucket should be deleted after a short period.
|
|
36
|
-
- The stack should be deletable without any remaining constructs or files.
|
|
37
|
-
|
|
38
|
-
## Proposed Solution
|
|
39
|
-
|
|
40
|
-
The `cdk-extensions` are currently already used to instantiate stacks based on the provided configuration files. The entry point is the `createApp` function in the file `configFileParsings.ts`. This is the point where we can extend the stack generation and instrument it to generate custom stages. Further, we can extend the constructs and extensions provided by the `cdk-extensions` to allow deactivating them.
|
|
41
|
-
|
|
42
|
-
### Separate Developer Stack
|
|
43
|
-
|
|
44
|
-
Currently, the stack is generated from the configuration files using the `createApp` function. The stage ID is set via the contents of a specified directory, i.e. all configuration files in the directory are used as stage, and can be controlled by the variable `CDK_STAGE`, i.e. if the variable is set to a stage id, only the given stage will be generated and used.
|
|
45
|
-
|
|
46
|
-
We propose to adjust the function s.t. we use the given stage id, but extend it with a suffix that identifies it as the developer's custom stack and stage. This can be achieved by a new environment variable. If the `DEVELOPER_STAGE_SUFFIX` environment variable is set, the value is appended to the stage id. Otherwise, the original id is used. This enables us to re-use an existing stacks and stage configurations, e.g. the one used for the development environment, without having to create a configuration file for each developer.
|
|
47
|
-
|
|
48
|
-
With these changes, the developer is now able to generate and deploy a custom stage e.g. based on an existing developer stage by just setting two variables. Assuming that the developer stage is called `dev-env` and the developer has the initials `AbCd`, setting `CDK_STAGE=dev-env` and `DEVELOPER_STAGE_SUFFIX=AbCd` before deploying the stage will deploy a custom developer stage with the ID `dev-env-AbCd` without any required adjustments to the stack or the stage configuration file.
|
|
49
|
-
|
|
50
|
-
### Partial Stack Deployment
|
|
51
|
-
|
|
52
|
-
Within the stack code, constructs are added with custom IDs. With these IDs, the constructs can unambiguously identified. We propose to use the IDs to declare the constructs to be omitted from the stack by providing them in an environment variable This enables the developer to deactivate components while no modification to the stack's source code is required.
|
|
53
|
-
|
|
54
|
-
We propose the introduction of a new environment variable `DEACTIVATED_CONSTRUCTS` that may contain a space-separated list of component IDs that shall be deactivated during stack synthetization.
|
|
55
|
-
|
|
56
|
-
For the considered use-case, it is sufficient to deactivate single constructs, thus no mechanism to deactivate groups of constructs is required.
|
|
57
|
-
|
|
58
|
-
To not create a Cloud Formation template with missing references, we propose not to remove the constructs, but rather deactivate them. What this means is based on the constructs.
|
|
59
|
-
|
|
60
|
-
For ECS containers, deactivating means that the number of desired instances is set to 0, preventing containers to be started while still being able to reference them. The containers them will not be able to consume messages from the SQS queue.
|
|
61
|
-
|
|
62
|
-
For the other use-case, batch executions, we can deactivate the Event Pipe that triggers the batch execution. This can be done by deploying the Event Pipe with the desired state `STOPPED` which will cause it to be present, but not consuming messages from the triggering SQS queue.
|
|
63
|
-
|
|
64
|
-
### File Retainment and Clean Deletion
|
|
65
|
-
|
|
66
|
-
Deletion of a stack deployment will remove all artifacts that have been created during deployment. However, there is a limitation for S3 Buckets that they, based on their configuration, will not be able to be deleted when they still contain files. Further, buckets have no data expiration time by default, thus all files will remain indefinitely.
|
|
67
|
-
|
|
68
|
-
We propose to provide a custom construct for S3 buckets that automatically sets the required parameters for data expiration and bucket removal when a developer stack instance is deployed. Besides using a different construct, no changes in the stack's implementation are required.
|
|
69
|
-
|
|
70
|
-
### Technical Implementation
|
|
71
|
-
|
|
72
|
-
This section describes the required changes to the `cdk-extensions` to implement the proposed solutions.
|
|
73
|
-
|
|
74
|
-
#### Implementation of Separate Developer Stacks
|
|
75
|
-
|
|
76
|
-
As mentioned before, the `createApp` function is used to instantiate the stacks. The stage ID is set via the name of the configuration file and filtered via the variable `CDK_STAGE`.
|
|
77
|
-
|
|
78
|
-
As mentioned in the proposal, we want to extend the ID with a suffix for the developer. We can achieve this by providing a function to generate the stage id based on the given id and a possible set environment variable.
|
|
79
|
-
|
|
80
|
-
const stageSuffixVariable = "DEVELOPER_STAGE_SUFFIX";
|
|
81
|
-
|
|
82
|
-
function generateId(id: string): string {
|
|
83
|
-
let stageSuffixValue = process.env[stageSuffixVariable];
|
|
84
|
-
if (stageSuffixValue !== undefined) {
|
|
85
|
-
if (!stageSuffixValue.match(/^[a-zA-Z0-9]+$/)) {
|
|
86
|
-
throw new Error(
|
|
87
|
-
`The value set in ${stageSuffixVariable} may not be empty and may only contain alphanumeric characters.`,
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
return `${id}-${stageSuffixValue}`;
|
|
91
|
-
}
|
|
92
|
-
return id;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
If the `DEVELOPER_STAGE_SUFFIX` environment variable is set, the function appends the value (if valid) to the stack ID. Otherwise, the original id is returned.
|
|
96
|
-
|
|
97
|
-
To use the possibly adjusted id, we have to extend the `AppStage` class that is used within the `createApp` function to use the new id generation function.
|
|
98
|
-
|
|
99
|
-
class AppStage extends Stage {
|
|
100
|
-
constructor(
|
|
101
|
-
scope: Construct,
|
|
102
|
-
id: string,
|
|
103
|
-
props: StageProps,
|
|
104
|
-
stackConfig: T,
|
|
105
|
-
) {
|
|
106
|
-
super(scope, generateId(id), props);
|
|
107
|
-
createStack(this, stackConfig);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// ...
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
These changes enable to implement the proposed deployment process. No adjustments to the individual stack implementations are required and the deployment is only controlled by the environment variables.
|
|
114
|
-
|
|
115
|
-
#### Implementation of Partial Stack Deployment
|
|
116
|
-
|
|
117
|
-
As mentioned before, the implementation is dependent on the construct to be deactivated. In our proposal, we focus on deactivating containers and Event Pipes. The following sections describe the proposed extensions to the `cdk-extensions`.
|
|
118
|
-
|
|
119
|
-
##### General Helper Function
|
|
120
|
-
|
|
121
|
-
A general function that allows to parse the environment variable `DEACTIVATED_CONSTRUCTS` is proposed as follows.
|
|
122
|
-
|
|
123
|
-
const deactivatedConstructsVariable = "DEACTIVATED_CONSTRUCTS";
|
|
124
|
-
|
|
125
|
-
export function isDeactivatedConstruct(name: string): boolean {
|
|
126
|
-
let deactivatedConstructsValue = process.env[deactivatedConstructsVariable];
|
|
127
|
-
if (deactivatedConstructsValue) {
|
|
128
|
-
const deactivatedComponents = deactivatedConstructsValue
|
|
129
|
-
? deactivatedConstructsValue.split(/\s+/)
|
|
130
|
-
: [];
|
|
131
|
-
if (deactivatedComponents.includes(name)) {
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
Using this function, the following implementations can easily determine, if a construct is marked to be deactivated and no separate parsers have to be implemented.
|
|
139
|
-
|
|
140
|
-
##### Containers
|
|
141
|
-
|
|
142
|
-
Containers are currently created using a `Service` that is using an extensible `ServiceDescription`. The `cdk-extensions` provide a set of extensions for the `ServiceDescription`.
|
|
143
|
-
|
|
144
|
-
We propose to provide a new extension `DeactivateableServiceExtension`. This extension can be used the same way as the currently existing service extension.
|
|
145
|
-
|
|
146
|
-
By adding a single line of code to the CDK implementation, the new extension can be used and thus the service for the container can be deactivated.
|
|
147
|
-
|
|
148
|
-
const serviceDescription = new ServiceDescription();
|
|
149
|
-
// add further extensions
|
|
150
|
-
// ...
|
|
151
|
-
serviceDescription.add(new DeactivatableServiceExtension());
|
|
152
|
-
|
|
153
|
-
With this extension in use, the developer can deactivate the construct by adding the ID of the service to the `DEACTIVATED_CONSTRUCTS` variable.
|
|
154
|
-
|
|
155
|
-
The extension can be implemented as follows.
|
|
156
|
-
|
|
157
|
-
export class DeactivatableServiceExtension extends ServiceExtension {
|
|
158
|
-
constructor() {
|
|
159
|
-
super("deactivatable-service");
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
modifyServiceProps(props: ServiceBuild): ServiceBuild {
|
|
163
|
-
if (isDeactivatedConstruct(this.parentService.id)) {
|
|
164
|
-
Annotations.of(this.parentService).addInfo(
|
|
165
|
-
`${this.parentService.id} is set to be deactivated.`,
|
|
166
|
-
);
|
|
167
|
-
return {
|
|
168
|
-
...props,
|
|
169
|
-
desiredCount: 0,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
return props;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
The extension will set the `desiredCount` for the task in the service properties, effectively deactivating the task while still retaining the definition.
|
|
177
|
-
|
|
178
|
-
##### Event Pipes
|
|
179
|
-
|
|
180
|
-
There is currently no implementation for an Event Pipe in the `cdk-extensions`. Defining an Event Pipe in the CDK implementation requires the use of an L1 construct. Therefore, we propose to provide a new construct for implementing the currently required use-cases for Event Pipes in the `cdk-extensions` that also allows to deactivate the Event Pipe. Implementing an own construct supports the developers, as it helps them to define filters and templates, as those will otherwise only be validated on deployment. The currently required use-cases are to have an SQS queue as source and another queue or a StepFunction as target.
|
|
181
|
-
|
|
182
|
-
The implementation of the construct goes beyond the scope of this document. However, the implementation has to set the attribute `desiredState` of the `CfnPipeProps` passed to the `CfnPipe` constructor to `STOPPED`, if the ID of the pipe is contained in the list of deactivated constructs. We try to illustrate this in the following code snippet.
|
|
183
|
-
|
|
184
|
-
export class EventPipe extends Construct {
|
|
185
|
-
constructor(scope: Construct, id: string, props: EventPipeProps) {
|
|
186
|
-
super(scope, id);
|
|
187
|
-
|
|
188
|
-
// ...
|
|
189
|
-
|
|
190
|
-
let desiredState = "RUNNING";
|
|
191
|
-
if (isDeactivatedConstruct(id)) {
|
|
192
|
-
Annotations.of(this).addInfo(`${id} is set do be deactivated.`);
|
|
193
|
-
desiredState = "STOPPED";
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// ...
|
|
197
|
-
|
|
198
|
-
new CfnPipe(this, "EventPipe", {
|
|
199
|
-
desiredState: desiredState,
|
|
200
|
-
// further properties
|
|
201
|
-
// ...
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
This implementation will deploy a deactivated Event Pipe as `STOPPED`, preventing it from being executed.
|
|
207
|
-
|
|
208
|
-
#### Implementation of Bucket Behavior
|
|
209
|
-
|
|
210
|
-
The correct behavior of the bucket can be enforced by providing a custom construct that detects if a developer stack instance is deployed and sets the correct parameters for the original bucket construct.
|
|
211
|
-
|
|
212
|
-
function adjustProps(props?: BucketProps): BucketProps {
|
|
213
|
-
if (isDeveloperStack()) {
|
|
214
|
-
return {
|
|
215
|
-
...props,
|
|
216
|
-
removalPolicy: RemovalPolicy.DESTROY,
|
|
217
|
-
autoDeleteObjects: true,
|
|
218
|
-
lifecycleRules: [
|
|
219
|
-
{
|
|
220
|
-
expiration: Duration.days(3),
|
|
221
|
-
abortIncompleteMultipartUploadAfter: Duration.days(1),
|
|
222
|
-
},
|
|
223
|
-
],
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
return { ...props };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export class S3Bucket extends Bucket {
|
|
230
|
-
constructor(scope: Construct, id: string, props?: BucketProps) {
|
|
231
|
-
super(scope, id, adjustProps(props));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
If a developer stack is deployed (detectable by checking for the presence of the environment variable `DEVELOPER_STAGE_SUFFIX`), the correct removal policy as well as the option to delete objects on removal are set. Further, all objects are set to expire after 3 days. If no developer stack is deployed, the original properties are used. As the original `Bucket` construct is extended, no adjustments besides changing the construct creation are required in the stack implementation.
|
|
236
|
-
|
|
237
|
-
### Caveats
|
|
238
|
-
|
|
239
|
-
There are some caveats that have to be considered when providing the developer stacks for each project.
|
|
240
|
-
|
|
241
|
-
#### Available Constructs
|
|
242
|
-
|
|
243
|
-
It is not possible for the developer to retrieve a list of constructs that are available and able to be deactivated without reading the source code of the stack. A list of available values should be provided. As only a small set of constructs is expected to be deactivated, the effort for this is not that high.
|
|
244
|
-
|
|
245
|
-
#### Supported Constructs
|
|
246
|
-
|
|
247
|
-
As the deactivation is performed on L2 by deactivating constructs using their respective mechanism, only supported constructs can be deactivated. If more that the currently provided constructs are required to be deactivated, support for this has to be added to the `cdk-extensions`.
|
|
248
|
-
|
|
249
|
-
#### Deployment Support
|
|
250
|
-
|
|
251
|
-
To support the developers in using the developer stage, we can provide a custom Projen/Yarn script to interact with the developer stage.
|
|
252
|
-
|
|
253
|
-
This can be achieved by extending the `.projenrc.ts` file of the project or providing Projen templates with the setting already set.
|
|
254
|
-
|
|
255
|
-
project.addScripts({
|
|
256
|
-
"cdk-dev":
|
|
257
|
-
'export DEVELOPER_STAGE_SUFFIX="$(git config user.alias)" && export CDK_STAGE="btc-es-dev-eu" && cdk',
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
In the shown example, the developer stage name is taken from the Git configuration. Another source for an unambiguous identifier could be chosen. The content of the variable is checked within the `cdk-extensions` code.
|
|
261
|
-
|
|
262
|
-
#### Unique Names
|
|
263
|
-
|
|
264
|
-
Some component, e.g. Batch queue names or job definitions, do not have unique names in the stacks, i.e. deploying multiple stacks or multiple stages of the stack in the same account could lead to an error due to conflicting names. This has to be considered when developing the stack and the stage name might be added to the names.
|
|
265
|
-
|
|
266
|
-
#### Multiple Stack Deployments
|
|
267
|
-
|
|
268
|
-
For some projects, the stack is split into multiple projects, i.e. it is not deployed as a single stack but a combination of multiple stacks. This can be an issue, if the stacks depend on each other and elements are linked e.g. by their ARN. For generic dependencies like VPCs or security groups, this is not an issue, as there should be no issue, if multiple developer stages use the same VPC. This potential limitation has to be taken into consideration when designing the stacks.
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# Referencing platform components in application-level stacks
|
|
2
|
-
|
|
3
|
-
The CDK extensions library provides components which are intended to be
|
|
4
|
-
instantiated in a _base platform_ stack as well as an _application-level_ stack.
|
|
5
|
-
Such resources (and their functionality) should then be accessible to services
|
|
6
|
-
developed and maintained in independently deployed, _application-level_ CDK
|
|
7
|
-
apps. This document describes the platform component interface to provide this
|
|
8
|
-
functionality.
|
|
9
|
-
|
|
10
|
-
## Platform component interface
|
|
11
|
-
|
|
12
|
-
Technically, the application-level stack references base platform components
|
|
13
|
-
with the help of stack output parameters. To encapsulate this aspect, every base
|
|
14
|
-
platform component has a static method `fromBasePlatform(scope: Construct, id:
|
|
15
|
-
string, name: string)` which, given the base platform stack name, returns an
|
|
16
|
-
instance of the platform component where the required lookup has been performed.
|
|
17
|
-
|
|
18
|
-
The resulting component instance then supports access to base platform component
|
|
19
|
-
properties or can even provide operations to the application-level stack (i.e.
|
|
20
|
-
registering a target group to an ALB). Example:
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
export interface IPlatformComponent {
|
|
24
|
-
readonly property: IVpcLink;
|
|
25
|
-
readonly securityGroup: ISecurityGroup;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class PlatformComponent extends Construct implements IPlatformComponent {
|
|
29
|
-
public static fromBasePlatform(
|
|
30
|
-
scope: Construct,
|
|
31
|
-
id: string,
|
|
32
|
-
name: string,
|
|
33
|
-
): IPlatformComponent {
|
|
34
|
-
// ... code requird to look up the output parameters ...
|
|
35
|
-
|
|
36
|
-
class Import extends Construct implements IApiGatewayV2 {
|
|
37
|
-
public readonly securityGroup: ISecurityGroup = /* ... */;
|
|
38
|
-
public readonly vpcLink: IVpcLink = /* ... */;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// create an instance satisfying the interface defined above
|
|
42
|
-
return new Import(scope, id);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
readonly property: IVpcLink;
|
|
46
|
-
readonly securityGroup: ISecurityGroup;
|
|
47
|
-
|
|
48
|
-
// ... further component code, constructor, ...
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
In more complex scenarios where functionality should be provided to the
|
|
53
|
-
application-level stack, we can use a base class in order to provide
|
|
54
|
-
functionality in the interface, such that it is also available at the platform
|
|
55
|
-
component instance.
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
|
|
59
|
-
export interface IPlatformComponent {
|
|
60
|
-
readonly property: IVpcLink;
|
|
61
|
-
readonly securityGroup: ISecurityGroup;
|
|
62
|
-
|
|
63
|
-
doSomething(target: IConnectable): void;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export abstract class PlatformComponentBase extends Construct implements IPlatformComponent {
|
|
67
|
-
abstract readonly property: IVpcLink;
|
|
68
|
-
abstract readonly securityGroup: ISecurityGroup;
|
|
69
|
-
|
|
70
|
-
doSomething(target: IConnectable) {
|
|
71
|
-
securityGroup.allowFrom(target);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export class PlatformComponent extends PlatformComponentBase {
|
|
76
|
-
public static fromBasePlatform(
|
|
77
|
-
scope: Construct,
|
|
78
|
-
id: string,
|
|
79
|
-
name: string,
|
|
80
|
-
): IPlatformComponent {
|
|
81
|
-
// ... code requird to look up the output parameters ...
|
|
82
|
-
|
|
83
|
-
class Import extends PlatformComponentBase {
|
|
84
|
-
readonly securityGroup: ISecurityGroup = /* ... */;
|
|
85
|
-
readonly vpcLink: IVpcLink = /* ... */;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// create an instance satisfying the interface defined above
|
|
89
|
-
return new Import(scope, id);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
readonly property: IVpcLink;
|
|
93
|
-
readonly securityGroup: ISecurityGroup;
|
|
94
|
-
|
|
95
|
-
// ... further component code, constructor, ...
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
This approach provides means to encapsulate component-specific handling of stack
|
|
100
|
-
parameters for transporting the information necessary to instantiate the
|
|
101
|
-
component interface in the application.
|
|
102
|
-
|
|
103
|
-
## Usage in the application-level stack
|
|
104
|
-
|
|
105
|
-
The example below shows how to use a base platform component in the
|
|
106
|
-
application-level stack:
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
// ...
|
|
110
|
-
|
|
111
|
-
const component = PlatformComponent.fromBasePlatform(
|
|
112
|
-
this.scope,
|
|
113
|
-
"PlatformComponent",
|
|
114
|
-
this.props.basePlatformStackName, // must be specified in the stack config
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
component.doSomething(service);
|
|
118
|
-
|
|
119
|
-
// ...
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
During CDK synthesis, this code will instantiate the necessary lookups to the
|
|
123
|
-
parameters exposed by the base platform. The interface returned by the static
|
|
124
|
-
lookup method allows us to explicitly state the base platform component
|
|
125
|
-
capabilities in the context of the application-level CDK.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
status: Accepted
|
|
3
|
-
date: 2025-04-07
|
|
4
|
-
deciders: Cloud Architecture & Technololgy
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# AD: Use ADRs to Document Architecture decision
|
|
8
|
-
|
|
9
|
-
## Context and Problem Statement
|
|
10
|
-
|
|
11
|
-
Architecture decisions are not visibile from the code strucutre itself. These decisions are therefor prone to be reiteratied on multiple times.
|
|
12
|
-
|
|
13
|
-
## Decision Drivers
|
|
14
|
-
|
|
15
|
-
* Desire to have a comprehensive documentation of the system
|
|
16
|
-
* Have a industrie standard for documentation of architecture decisions
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
## Considered Options
|
|
20
|
-
|
|
21
|
-
1. Ad hoc documents
|
|
22
|
-
2. Architecture Decision Records (ADRs)
|
|
23
|
-
|
|
24
|
-
## Decision Outcome
|
|
25
|
-
|
|
26
|
-
We decided on using ADRs since it is the only of the two options satisfying all decision drivers.
|
|
27
|
-
|
|
28
|
-
### Consequences
|
|
29
|
-
|
|
30
|
-
* Good, architecture decisions are documented.
|
|
31
|
-
* Bad, you have to write an ADR for every decision.
|
|
32
|
-
|
|
33
|
-
## More Information
|
|
34
|
-
|
|
35
|
-
* See the link to the definiton of Architecture Decision Records [https://adr.github.io/](https://adr.github.io/)
|
|
36
|
-
* See the link to the MADR Desicion tempates for more information on the temaplate [https://github.com/adr/madr/tree/3.0.0](https://github.com/adr/madr/tree/3.0.0)
|
package/docs/index.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Project Structure Documentation
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
The project is organized into the following directories and files:
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
/src
|
|
8
|
-
├── constructs
|
|
9
|
-
├── extensions
|
|
10
|
-
├── platform
|
|
11
|
-
├── utils
|
|
12
|
-
/docs
|
|
13
|
-
/test
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
# To Install it run
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm i @btc-embedded/cdk-extensions
|
|
20
|
-
```
|