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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(continuous-delivery): assets in environment-agnostic stacks #93

Merged
merged 5 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions text/0049-continuous-delivery.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ _Non-requirements/assumptions:_
* We assume that **cdk.context.json** is committed into the repo. Any context-fetching will be done manually by users and committed to the repository.
* There’s a one-to-one mapping between an app and a pipeline. We are not optimizing the experience for multiple apps per pipeline (although technically it should be possible to do it, but it’s not a use case we are focused on).
* Dependency management, repository and project structure are out of scope: we don’t want to be opinionated about how users should structure their projects. They should be able to use the tools they are familiar with and are available to their teams to structure and modularize their applications.
* Assets will not be supported in environment-agnostic stacks. [#4131](https://github.com/aws/aws-cdk/pull/4131) proposes that `cdk deploy` will default `env` to the current account/region, which means that the CLI use case will no longer treat stacks as environment-agnostic.

## Approach

Expand Down Expand Up @@ -186,17 +185,33 @@ Users should be able to vend custom asset providers to allow customizing how ass

For example, a company might have an internal system that manages software artifacts. They can internally vend custom implementations for the `lambda.Code` and `ecs.ContainerImage` classes which will allow users to reference these artifacts and synthesize placeholders into the cloud assembly, which will later be resolved during the publishing stage and identified through a user-defined unique identifier.

**Environment-agnostic Stacks**
**Environment-Agnostic Stacks**

When a stack is defined, users can specify `env` (account and/or region).
When a stack is defined, users can specify the target environment (account/region) into which the stack is deployed via the `env` option.

If `account` and/or `region` use the pseudo references `Aws.ACCOUNT_ID` and `Aws.REGION`, respectively, the stack is called "environment-agnostic". Certain features in the CDK, like VPC lookups for example, are not supported for environment-agnostic stacks since the specific account/region is required during synthesis.

The proposal described in [PR#4131](https://github.com/aws/aws-cdk/pull/4131) suggests that environment-agnostics stacks cannot be deployed using the CDK. However, it also proposes that the default behavior for `env` will be to use ("inherit") the CLI configured environment when a stack is deployed through `cdk deploy`.
When synthesizing the location of an asset into a CloudFormation template for environment-agnostic stacks based on the conventional bootstrap names, the result will look something like this:

This means that the only way to produce environment-agnostic templates will be to explicitly indicate it when a stack is defined.
```json
{
"Fn::Join": [ "", [
"cdk-bootstrap-hnb659fds-container-assets-",
{ "Ref": "AWS::AccountId" }, "-", { "Ref": "AWS::Region" },
":7a4f25ddcb08358916501c7536cdb11f33daf856896aa2a2bec3c7a5d735ace4"
] ]
}
```

When a template that contains this expression will be deployed, CloudFormation will resolve this to the correct location within the current account and region.

However, we also need to be able to express this environment-agnostic location in `assets.json`. This can be done either by adding explicit support for `Fn::Join` and the region/account pseudo references in their CloudFormation syntax or by rendering a substitution syntax such as:

```
cdk-bootstrap-hnb659fds-container-assets-${AWS::ACCOUNT}-${AWS::REGION}:7a4f25ddcb08358916501c7536cdb11f33daf856896aa2a2bec3c7a5d735ace4
```

Since the specific account and region are required when resolving asset consumption and publishing locations, the current plan is for the default asset store implementation to **fail if assets are used from environment-agnostic stacks**. Again, bear in mind that the current behavior (where the default is environment-agnostic stacks) is going to be changed.
When `cdk-assets` needs to publish an asset it will substitute `${AWS::ACCOUNT}` and `${AWS::REGION}` with the current account and region.
eladb marked this conversation as resolved.
Show resolved Hide resolved

## Bootstrapping

Expand Down
5 changes: 4 additions & 1 deletion text/0092-asset-publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ The main components of the assets manifest are:

* **Destinations:** describe where the asset should be published. At a minimum, for file assets, it includes the S3 bucket and object key and for docker images it includes the repository and image names. A destination may also indicate that an IAM role must be assumed in order to support cross environment publishing.

> Destinations are intentionally denormalized in order to keep the logic of where assets are published at the application or framework level and not in this tool. For example, consider a deployment system which requires that all assets are always published to the same location, and then replicated through some other means to their actual consumption point. Alternatively, a user may have unique security requirements that will require certain assets to be stored in dedicated locations (e.g. with a specific key) and others in a different location, even if they all go to the same environment. Therefore, this tool should not take any assumptions on where assets should be published besides the exact instructions in this file.
NOTES:

* **Denormalization:** destinations are intentionally denormalized in order to keep the logic of where assets are published at the application or framework level and not in this tool. For example, consider a deployment system which requires that all assets are always published to the same location, and then replicated through some other means to their actual consumption point. Alternatively, a user may have unique security requirements that will require certain assets to be stored in dedicated locations (e.g. with a specific key) and others in a different location, even if they all go to the same environment. Therefore, this tool should not take any assumptions on where assets should be published besides the exact instructions in this file.
* **Environment-agnostic:** In order to allow assets to be used in environment-agnostic stacks, `assets.json` will support two simple substitutions `${AWS::AccountId}` and `${AWS::Region}` which will be replaced with the currently configured account/region (alternatively, we can also decide to support CloudFormation intrinsic functions and pseudo references).

Here is the complete manifest file schema in typescript:

Expand Down