Decouple asset packaging and publishing #668
Labels
@aws-cdk/assets
Related to the @aws-cdk/assets package
feature-request
A feature should be added or improved.
This came up while looking at our current asset implementation.
Currently
assets.Asset
is a concrete class that does a number of things, such as adding metadata and parameters to the template. The presence of these fields leads to the toolkit uploading data to S3.lambda.AssetCode
is a concrete class that instantiates anassets.Asset
class with apath
andpackaging
parameter.First observation: there is no way to treat something as Lambda AssetCode UNLESS this involves packaging and uploading some files somewhere. In particular, some files that are published out-of-band could and should be treated like assets as well, but they don't involve the upload machinery of current assets, plus they are referenced differently. Because of the concrete class dependency, there is also no way to make a
PipelineAsset
, because MUST extendassets.Asset
, and MUST callsuper()
which will generate metadata that will make the toolkit try to do something. We don't want that.Second observation: but is introducing a class that behaves differently actually desirable? We probably still want to say
new ZipDirectoryAsset({ path: './my-files' })
regardless of the publishing method. In fact, that is desirable so that the same project can be deployed via a pipeline for production accounts as well as from the command-line for developer accounts.So we want the
assets.Asset
class to say something about packaging, but not about publishing. In fact, we want to defer the choice of what publishing method to use to synthesis time.This is all well and achievable, but the next problem is that we want to refer to the published artifacts as well; it's helpful if the
assets.Asset
class is aware of what to inject into the CloudFormation template to refer to the published artifact--unfortunately (but also obviously), this depends on the publishing method.What happens
DEPLOYING USING COMMAND LINE
CODEPIPELINE
{Fn::GetArtifactAtt}
)(In practice, we're probably going to use the toolkit to upload to S3 as well on CodeBuild because of the restrictions on artifacts--but we still want this to be extensible to support more types of publishing)
Asset references
COMMAND LINE
CODEPIPELINE
Tricky part here is that
ArtifactName
is decided in the pipeline, so we should pass it into the build step in some way so that it can be properly output in the synthesis step.Proposal
To be most generic, we should probably split asset handling into 2 phases (just like we do with missing context).
In the first synthesis phase, the app reports the assets and their expected packaging methods.
The CDK then packages and publishes according to the selected publishing method (
--publish=direct
,--publish=codepipeline
or similar). The publishing step may not do anything other than put files in a certain location.In the second synthesis phase, synthesis is run again and the toolkit uses context to pass data on how to reference the assets to the
Asset
class, which uses the context to return the appropriate attributes.If we remove the
S3ObjectKeyParameter
from the command-line assets implementation, and just pass in the literal hash of the ZIP file that was produced during packaging, we'll immediately have solved #395 as well.If the publishing method starts with the magic string
plugin-
, as in:Then the NPM package
aws-cdk-plugin-something
is loaded and used for publishing.The text was updated successfully, but these errors were encountered: