Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@aws-cdk/app-staging-synthesizer-alpha
Advanced tools
Cdk synthesizer for with app-scoped staging stack
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 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.
This library includes constructs aimed at replacing the current model of bootstrapping and providing greater control of the bootstrap experience to the CDK user. The important constructs in this library are as follows:
IStagingResources
interface: a framework for an app-level bootstrap stack that handles
file assets and docker assets.DefaultStagingStack
, which is a works-out-of-the-box implementation of the IStagingResources
interface.AppStagingSynthesizer
, a new CDK synthesizer that will synthesize CDK applications with
the staging resources provided.As this library is
experimental
, there are features that are not yet implemented. Please look at the list of Known Limitations before getting started.
To get started, update your CDK App with a new defaultStackSynthesizer
:
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id', // put a unique id here
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
}),
});
This will introduce a DefaultStagingStack
in your CDK App and staging assets of your App
will live in the resources from that stack rather than the CDK Bootstrap stack.
If you are migrating from a different version of synthesis your updated CDK App will target
the resources in the DefaultStagingStack
and no longer be tied to the bootstrapped resources
in your account.
In our default bootstrapping process, when you run cdk bootstrap aws://<account>/<region>
, the following
resources are created:
Because the bootstrapping resources include regional resources, you need to bootstrap every region you plan to deploy to individually. All assets of all CDK apps deploying to that account and region will be written to the single S3 Bucket and ECR repository.
By using the synthesizer in this library, instead of the
DefaultStackSynthesizer
, a different set of staging resources will be created
for every CDK application, and they will be created automatically as part of a
regular deployment, in a separate Stack that is deployed before your application
Stacks. The staging resources will be one S3 bucket, and one ECR repository per
image, and Roles necessary to access those buckets and ECR repositories. The
Roles from the default bootstrap stack are still used (though their use can be
turned off).
This has the following advantages:
For the deployment roles, this synthesizer still uses the Roles from the default bootstrap stack, and nothing else. The staging resources from that bootstrap stack will be unused. You can customize the template to remove those resources if you prefer. In the future, we will provide a bootstrap stack template with only those Roles, specifically for use with this synthesizer.
The most common use case will be to use the built-in default resources. In this scenario, the
synthesizer will create a new Staging Stack in each environment the CDK App is deployed to store
its staging resources. To use this kind of synthesizer, use AppStagingSynthesizer.defaultResources()
.
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
// The following line is optional. By default it is assumed you have bootstrapped in the same
// region(s) as the stack(s) you are deploying.
deploymentIdentities: DeploymentIdentities.defaultBootstrapRoles({ bootstrapRegion: 'us-east-1' }),
}),
});
Every CDK App that uses the DefaultStagingStack
must include an appId
. This should
be an identifier unique to the app and is used to differentiate staging resources associated
with the app.
The Default Staging Stack includes all the staging resources necessary for CDK Assets. The below example
is of a CDK App using the AppStagingSynthesizer
and creating a file asset for the Lambda Function
source code. As part of the DefaultStagingStack
, an S3 bucket and IAM role will be created that will be
used to upload the asset to S3.
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
}),
});
const stack = new Stack(app, 'my-stack');
new lambda.Function(stack, 'lambda', {
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'assets')),
handler: 'index.handler',
runtime: lambda.Runtime.PYTHON_3_9,
});
app.synth();
You can customize some or all of the roles you'd like to use in the synthesizer as well,
if all you need is to supply custom roles (and not change anything else in the DefaultStagingStack
):
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
deploymentIdentities: DeploymentIdentities.specifyRoles({
cloudFormationExecutionRole: BootstrapRole.fromRoleArn('arn:aws:iam::123456789012:role/Execute'),
deploymentRole: BootstrapRole.fromRoleArn('arn:aws:iam::123456789012:role/Deploy'),
lookupRole: BootstrapRole.fromRoleArn('arn:aws:iam::123456789012:role/Lookup'),
}),
}),
});
Or, you can ask to use the CLI credentials that exist at deploy-time.
These credentials must have the ability to perform CloudFormation calls,
lookup resources in your account, and perform CloudFormation deployment.
For a full list of what is necessary, see LookupRole
, DeploymentActionRole
,
and CloudFormationExecutionRole
in the
bootstrap template.
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
deploymentIdentities: DeploymentIdentities.cliCredentials(),
}),
});
The default staging stack will create roles to publish to the S3 bucket and ECR repositories,
assumable by the deployment role. You can also specify an existing IAM role for the
fileAssetPublishingRole
or imageAssetPublishingRole
:
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
fileAssetPublishingRole: BootstrapRole.fromRoleArn('arn:aws:iam::123456789012:role/S3Access'),
imageAssetPublishingRole: BootstrapRole.fromRoleArn('arn:aws:iam::123456789012:role/ECRAccess'),
}),
});
There are two types of assets:
Examples of assets that are only used at deploy time are CloudFormation Templates and Lambda Code
bundles. Examples of assets accessed throughout the life time of the application are script files
downloaded to run in a CodeBuild Project, or on EC2 instance startup. ECR images are always application
life-time assets. S3 deploy time assets are stored with a deploy-time/
prefix, and a lifecycle rule will collect them after a configurable number of days.
Lambda assets are by default marked as deploy time assets:
declare const stack: Stack;
new lambda.Function(stack, 'lambda', {
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'assets')), // lambda marks deployTime = true
handler: 'index.handler',
runtime: lambda.Runtime.PYTHON_3_9,
});
Or, if you want to create your own deploy time asset:
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
declare const stack: Stack;
const asset = new Asset(stack, 'deploy-time-asset', {
deployTime: true,
path: path.join(__dirname, 'deploy-time-asset'),
});
By default, we store deploy time assets for 30 days, but you can change this number by specifying
deployTimeFileAssetLifetime
. The number you specify here is how long you will be able to roll back
to a previous version of an application just by doing a CloudFormation deployment with the old
template, without rebuilding and republishing assets.
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
deployTimeFileAssetLifetime: Duration.days(100),
}),
});
By default, we store a maximum of 3 revisions of a particular docker image asset. This allows for smooth faciliation of rollback scenarios where we may reference previous versions of an image. When more than 3 revisions of an asset exist in the ECR repository, the oldest one is purged.
To change the number of revisions stored, use imageAssetVersionCount
:
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
imageAssetVersionCount: 10,
}),
});
By default, the staging resources will be cleaned up on stack deletion. That means that the
S3 Bucket and ECR Repositories are set to RemovalPolicy.DESTROY
and have autoDeleteObjects
or emptyOnDelete
turned on. This creates custom resources under the hood to facilitate
cleanup. To turn this off, specify autoDeleteStagingAssets: false
.
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
appId: 'my-app-id',
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
autoDeleteStagingAssets: false,
}),
});
You must explicitly specify the encryption type for the staging bucket via the stagingBucketEncryption
property. In
future versions of this package, the default will be BucketEncryption.S3_MANAGED
.
In previous versions of this package, the default was to use KMS encryption for the staging bucket. KMS keys cost $1/month, which could result in unexpected costs for users who are not aware of this. As we stabilize this module we intend to make the default S3-managed encryption, which is free. However, the migration path from KMS to S3 managed encryption for existing buckets is not straightforward. Therefore, for now, this property is required.
If you have an existing staging bucket encrypted with a KMS key, you will likely want to set this property to
BucketEncryption.KMS
. If you are creating a new staging bucket, you can set this property to
BucketEncryption.S3_MANAGED
to avoid the cost of a KMS key.
You can learn more about choosing a bucket encryption type in the S3 documentation.
If you want to customize some behavior that is not configurable via properties,
you can implement your own class that implements IStagingResources
. To get a head start,
you can subclass DefaultStagingStack
.
interface CustomStagingStackOptions extends DefaultStagingStackOptions {}
class CustomStagingStack extends DefaultStagingStack {
}
Or you can roll your own staging resources from scratch, as long as it implements IStagingResources
.
interface CustomStagingStackProps extends StackProps {}
class CustomStagingStack extends Stack implements IStagingResources {
public constructor(scope: Construct, id: string, props: CustomStagingStackProps) {
super(scope, id, props);
}
public addFile(asset: FileAssetSource): FileStagingLocation {
return {
bucketName: 'amzn-s3-demo-bucket',
assumeRoleArn: 'myArn',
dependencyStack: this,
};
}
public addDockerImage(asset: DockerImageAssetSource): ImageStagingLocation {
return {
repoName: 'myRepo',
assumeRoleArn: 'myArn',
dependencyStack: this,
};
}
}
Using your custom staging resources means implementing a CustomFactory
class and calling the
AppStagingSynthesizer.customFactory()
static method. This has the benefit of providing a
custom Staging Stack that can be created in every environment the CDK App is deployed to.
class CustomFactory implements IStagingResourcesFactory {
public obtainStagingResources(stack: Stack, context: ObtainStagingResourcesContext) {
const myApp = App.of(stack);
return new CustomStagingStack(myApp!, `CustomStagingStack-${context.environmentString}`, {});
}
}
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.customFactory({
factory: new CustomFactory(),
oncePerEnv: true, // by default
}),
});
Use AppStagingSynthesizer.customResources()
to supply an existing stack as the Staging Stack.
Make sure that the custom stack you provide implements IStagingResources
.
const resourceApp = new App();
const resources = new CustomStagingStack(resourceApp, 'CustomStagingStack', {});
const app = new App({
defaultStackSynthesizer: AppStagingSynthesizer.customResources({
resources,
}),
});
Since this module is experimental, there are some known limitations:
cdk deploy
. Please upvote this issue
to indicate you want this.FAQs
Cdk synthesizer for with app-scoped staging stack
We found that @aws-cdk/app-staging-synthesizer-alpha demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.