diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/README.md b/packages/@aws-cdk/aws-imagebuilder-alpha/README.md index 5855b6bb93871..9eb9853db3a7b 100644 --- a/packages/@aws-cdk/aws-imagebuilder-alpha/README.md +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/README.md @@ -36,6 +36,250 @@ EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketpl that you create. Components run during specific workflow phases: build and validate phases during the build stage, and test phase during the test stage. +### Component + +A component defines the sequence of steps required to customize an instance during image creation (build component) or +test an instance launched from the created image (test component). Components are created from declarative YAML or JSON +documents that describe runtime configuration for building, validating, or testing instances. Components are included +when added to the image recipe or container recipe for an image build. + +EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketplace components, and custom components +that you create. Components run during specific workflow phases: build and validate phases during the build stage, and +test phase during the test stage. + +#### Basic Usage + +Create a component with the required properties: platform and component data. + +```ts +const component = new imagebuilder.Component(this, 'MyComponent', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromJsonObject({ + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'install-app', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + inputs: { + commands: ['echo "Installing my application..."', 'yum update -y'], + }, + }, + ], + }, + ], + }), +}); +``` + +#### Component Data Sources + +##### Inline Component Data + +Use `ComponentData.fromInline()` for existing YAML/JSON definitions: + +```ts +const component = new imagebuilder.Component(this, 'InlineComponent', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromInline(` +name: my-component +schemaVersion: 1.0 +phases: + - name: build + steps: + - name: update-os + action: ExecuteBash + inputs: + commands: ['yum update -y'] +`) +}); +``` + +##### JSON Object Component Data + +Most developer-friendly approach using objects: + +```ts + +const component = new imagebuilder.Component(this, 'JsonComponent', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromJsonObject({ + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'configure-app', + action: imagebuilder.ComponentAction.CREATE_FILE, + inputs: { + path: '/etc/myapp/config.json', + content: '{"env": "production"}' + } + } + ] + } + ] + }) +}); +``` + +##### Structured Component Document + +For type-safe, CDK-native definitions with enhanced properties like `timeout` and `onFailure`. + +###### Defining a component step + +You can define steps in the component which will be executed in order when the component is applied: + +```ts +const step: imagebuilder.ComponentDocumentStep = { + name: 'configure-app', + action: imagebuilder.ComponentAction.CREATE_FILE, + inputs: imagebuilder.ComponentStepInputs.fromObject({ + path: '/etc/myapp/config.json', + content: '{"env": "production"}' + }) +}; +``` + +###### Defining a component phase + +Phases group steps together, which run in sequence when building, validating or testing in the component: + +```ts +const phase: imagebuilder.ComponentDocumentPhase = { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'configure-app', + action: imagebuilder.ComponentAction.CREATE_FILE, + inputs: imagebuilder.ComponentStepInputs.fromObject({ + path: '/etc/myapp/config.json', + content: '{"env": "production"}' + }) + } + ] +}; +``` + +###### Defining a component + +The component data defines all steps across the provided phases to execute during the build: + +```ts +const component = new imagebuilder.Component(this, 'StructuredComponent', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromComponentDocumentJsonObject({ + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'install-with-timeout', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + timeout: Duration.minutes(10), + onFailure: imagebuilder.ComponentOnFailure.CONTINUE, + inputs: imagebuilder.ComponentStepInputs.fromObject({ + commands: ['./install-script.sh'] + }) + } + ] + } + ] + }) +}); +``` + +##### S3 Component Data + +For those components you want to upload or have uploaded to S3: + +```ts +// Upload a local file +const componentFromAsset = new imagebuilder.Component(this, 'AssetComponent', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromAsset(this, 'ComponentAsset', './my-component.yml'), +}); + +// Reference an existing S3 object +const bucket = s3.Bucket.fromBucketName(this, 'ComponentBucket', 'my-components-bucket'); +const componentFromS3 = new imagebuilder.Component(this, 'S3Component', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromS3(bucket, 'components/my-component.yml'), +}); +``` + +#### Encrypt component data with a KMS key + +You can encrypt component data with a KMS key, so that only principals with access to decrypt with the key are able to +access the component data. + +```ts +const component = new imagebuilder.Component(this, 'EncryptedComponent', { + platform: imagebuilder.Platform.LINUX, + kmsKey: new kms.Key(this, 'ComponentKey'), + data: imagebuilder.ComponentData.fromJsonObject({ + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'secure-setup', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + inputs: { + commands: ['echo "This component data is encrypted with KMS"'], + }, + }, + ], + }, + ], + }), +}); +``` + +#### AWS-Managed Components + +AWS provides a collection of managed components for common tasks: + +```ts +// Install AWS CLI v2 +const awsCliComponent = imagebuilder.AwsManagedComponent.awsCliV2(this, 'AwsCli', { + platform: imagebuilder.Platform.LINUX +}); + +// Update the operating system +const updateComponent = imagebuilder.AwsManagedComponent.updateOS(this, 'UpdateOS', { + platform: imagebuilder.Platform.LINUX +}); + +// Reference any AWS-managed component by name +const customAwsComponent = imagebuilder.AwsManagedComponent.fromAwsManagedComponentName( + this, + 'CloudWatchAgent', + 'amazon-cloudwatch-agent-linux' +); +``` + +#### AWS Marketplace Components + +You can reference AWS Marketplace components using the marketplace component name and its product ID: + +```ts +const marketplaceComponent = imagebuilder.AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes( + this, + 'MarketplaceComponent', + { + componentName: 'my-marketplace-component', + marketplaceProductId: 'prod-1234567890abcdef0', + } +); +``` + ### Infrastructure Configuration Infrastructure configuration defines the compute resources and environment settings used during the image building diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/lib/component.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/component.ts new file mode 100644 index 0000000000000..7342fd1ac0e61 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/component.ts @@ -0,0 +1,1363 @@ +import * as cdk from 'aws-cdk-lib'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import { CfnComponent } from 'aws-cdk-lib/aws-imagebuilder'; +import * as kms from 'aws-cdk-lib/aws-kms'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as s3assets from 'aws-cdk-lib/aws-s3-assets'; +import { propertyInjectable } from 'aws-cdk-lib/core/lib/prop-injectable'; +import { Construct } from 'constructs'; +import * as yaml from 'yaml'; +import { OSVersion, Platform } from './os-version'; + +const COMPONENT_SYMBOL = Symbol.for('@aws-cdk/aws-imagebuilder-alpha.Component'); + +const LATEST_VERSION = 'x.x.x'; + +/** + * An EC2 Image Builder Component. + */ +export interface IComponent extends cdk.IResource { + /** + * The ARN of the component + * + * @attribute + */ + readonly componentArn: string; + + /** + * The name of the component + * + * @attribute + */ + readonly componentName: string; + + /** + * The version of the component + * + * @attribute + */ + readonly componentVersion: string; + + /** + * Grant custom actions to the given grantee for the component + * + * @param grantee The principal + * @param actions The list of actions + */ + grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant; + + /** + * Grant read permissions to the given grantee for the component + * + * @param grantee The principal + */ + grantRead(grantee: iam.IGrantable): iam.Grant; +} + +/** + * Properties for creating a Component resource + */ +export interface ComponentProps { + /** + * The component document content that defines the build, validation, or test steps to be executed during the image + * building process. + */ + readonly data: ComponentData; + + /** + * The operating system platform of the component. + */ + readonly platform: Platform; + + /** + * The name of the component. + * + * @default - a name is generated + */ + readonly componentName?: string; + + /** + * The version of the component. + * + * @default 1.0.0 + */ + readonly componentVersion?: string; + + /** + * The description of the component. + * + * @default None + */ + readonly description?: string; + + /** + * The change description of the component. Describes what change has been made in this version of the component, or + * what makes this version different from other versions. + * + * @default None + */ + readonly changeDescription?: string; + + /** + * The KMS key used to encrypt this component. + * + * @default - an Image Builder owned key will be used to encrypt the component. + */ + readonly kmsKey?: kms.IKey; + + /** + * The operating system versions supported by the component. + * + * @default None + */ + readonly supportedOsVersions?: OSVersion[]; + + /** + * The tags to apply to the component + * + * @default None + */ + readonly tags?: { [key: string]: string }; +} + +/** + * Properties for an EC2 Image Builder component + */ +export interface ComponentAttributes { + /** + * The ARN of the component + * + * @default - the ARN is automatically constructed if a componentName is provided, otherwise a componentArn is + * required + */ + readonly componentArn?: string; + + /** + * The name of the component + * + * @default - the name is automatically constructed if a componentArn is provided, otherwise a componentName is + * required + */ + readonly componentName?: string; + + /** + * The version of the component + * + * @default - the latest version of the component, x.x.x + */ + readonly componentVersion?: string; +} + +/** + * Properties for an EC2 Image Builder AWS-managed component + */ +export interface AwsManagedComponentAttributes { + /** + * The name of the AWS-managed component + * + * The name of the AWS-managed component. This is a required attribute when using the + * `this.fromAwsManagedComponentAttributes()` method. This parameter should not be provided when + * using the pre-defined managed component methods, such as `AwsManagedComponent.updateOS()` and + * `AwsManagedComponent.reboot()`. + * + * @default - none if using the pre-defined managed component methods, otherwise a platform is required when using + * `this.fromAwsManagedComponentAttributes()` + */ + readonly componentName?: string; + + /** + * The version of the AWS-managed component + * + * @default - the latest version of the component, x.x.x + */ + readonly componentVersion?: string; + + /** + * The platform of the AWS-managed component. This is a required attribute when using the pre-defined managed + * component methods, such as `AwsManagedComponent.updateOS()` and `AwsManagedComponent.reboot()`. This parameter + * should not be provided when using the `this.fromAwsManagedComponentAttributes()` method. + * + * @default - none if using `this.fromAwsManagedComponentAttributes()`, otherwise a platform is + * required when using the pre-defined managed component methods + */ + readonly platform?: Platform; +} + +/** + * Properties for an EC2 Image Builder AWS Marketplace component + */ +export interface AwsMarketplaceComponentAttributes { + /** + * The name of the AWS Marketplace component. This name should exclude the marketplace product ID from it + */ + readonly componentName: string; + + /** + * The marketplace product ID associated with the component + */ + readonly marketplaceProductId: string; + + /** + * The version of the AWS Marketplace component + * + * @default - the latest version of the component, x.x.x + */ + readonly componentVersion?: string; +} + +/** + * Properties of an EC2 Image Builder Component Document + */ +export interface ComponentDocument { + /** + * The schema version of the component + */ + readonly schemaVersion: ComponentSchemaVersion; + + /** + * The phases which define the grouping of steps to run in the build and test workflows of the image build. + */ + readonly phases: ComponentDocumentPhase[]; + + /** + * The name of the document + * + * @default None + */ + readonly name?: string; + + /** + * The description of the document + * + * @default None + */ + readonly description?: string; + + /** + * The constants to define in the document + * + * @default None + */ + readonly constants?: { [constantName: string]: ComponentConstantValue }; + + /** + * The parameters to define in the document + * + * @default None + */ + readonly parameters?: { [parameterName: string]: ComponentDocumentParameterDefinition }; +} + +/** + * The phase to run in a specific workflow in an image build, which define the steps to execute to customize or test + * the instance. + */ +export interface ComponentDocumentPhase { + /** + * The name of the phase + */ + readonly name: ComponentPhaseName; + + /** + * The list of steps to execute to modify or test the build/test instance + */ + readonly steps: ComponentDocumentStep[]; +} + +/** + * The step to run in a specific phase of the image build, which defines the step to execute to customize or test the + * instance. + */ +export interface ComponentDocumentStep { + /** + * The name of the step + */ + readonly name: string; + + /** + * The action to perform in the step + */ + readonly action: ComponentAction; + + /** + * Contains parameters required by the action to run the step + * + * @see https://docs.aws.amazon.com/imagebuilder/latest/userguide/toe-action-modules.html + */ + readonly inputs: ComponentStepInputs; + + /** + * The condition to apply to the step. If the condition is false, then the step is skipped + * + * @default - no condition is applied to the step and it gets executed + * + * @see https://docs.aws.amazon.com/imagebuilder/latest/userguide/toe-conditional-constructs.html + * @see https://docs.aws.amazon.com/imagebuilder/latest/userguide/toe-comparison-operators.html + */ + readonly if?: ComponentStepIfCondition; + + /** + * A looping construct defining a repeated sequence of instructions + * + * @default None + */ + readonly loop?: ComponentDocumentLoop; + + /** + * The timeout of the step + * + * @default - 120 minutes + */ + readonly timeout?: cdk.Duration; + + /** + * Specifies what the step should do in case of failure + * + * @default ComponentOnFailure.ABORT + */ + readonly onFailure?: ComponentOnFailure; +} + +/** + * The looping construct of a component defines a repeated sequence of instructions + */ +export interface ComponentDocumentLoop { + /** + * The name of the loop, which can be used to reference + * + * @default loop + */ + readonly name?: string; + + /** + * The for loop iterates on a range of integers specified within a boundary outlined by the start and end of the + * variables + * + * @default - none if `forEach` is provided. otherwise, `for` is required. + */ + readonly for?: ComponentDocumentForLoop; + + /** + * The forEach loop iterates on an explicit list of values, which can be strings and chained expressions + * + * @default - none if `for` is provided. otherwise, `forEach` is required. + */ + readonly forEach?: string[]; +} + +/** + * The for loop iterates on a range of integers specified within a boundary outlined by the start and end of the + * variables. The iterating values are in the set [start, end] and includes boundary values. + */ +export interface ComponentDocumentForLoop { + /** + * Starting value of iteration. Does not accept chaining expressions. + */ + readonly start: number; + /** + * Ending value of iteration. Does not accept chaining expressions. + */ + readonly end: number; + /** + * Difference by which an iterating value is updated through addition. It must be a negative or positive non-zero + * value. Does not accept chaining expressions. + */ + readonly updateBy: number; +} + +/** + * The value of a constant in a component document + */ +export class ComponentConstantValue { + /** + * Creates a string type constant in a component document + * + * @param value The value of the constant + */ + public static fromString(value: string): ComponentConstantValue { + return new ComponentConstantValue('string', value); + } + + /** + * The data type of the constant + */ + public readonly type: string; + + /** + * The value of the constant + */ + public readonly value: any; + + protected constructor(type: string, value: any) { + this.type = type; + this.value = value; + } +} + +/** + * The definition of the parameter + */ +export interface ComponentDocumentParameterDefinition { + /** + * The type of the parameter + */ + readonly type: ComponentParameterType; + + /** + * The default value of the parameter + * + * @default - none, indicating the parameter is required + */ + readonly default?: any; + + /** + * The description of the parameter + * + * @default None + */ + readonly description?: string; +} + +/** + * The action for a step within the component document + */ +export enum ComponentAction { + /** + * The AppendFile action adds the provided content to the pre-existing content of a file + */ + APPEND_FILE = 'AppendFile', + + /** + * The Assert action performs value with comparison/logic operators, and succeeds/fails the step based on the outcome + * of the assertion + */ + ASSERT = 'Assert', + + /** + * The CopyFile action copies files from a source file to a destination + */ + COPY_FILE = 'CopyFile', + + /** + * The CopyFolder action copies folders from a source to a destination + */ + COPY_FOLDER = 'CopyFolder', + + /** + * The CreateFile action creates a file in the provided location + */ + CREATE_FILE = 'CreateFile', + + /** + * The CreateFolder action creates a folder in the provided location + */ + CREATE_FOLDER = 'CreateFolder', + + /** + * The CreateSymlink action creates symbolic links from a given path to a target + */ + CREATE_SYMLINK = 'CreateSymlink', + + /** + * The DeleteFile action deletes file(s) in the provided location + */ + DELETE_FILE = 'DeleteFile', + + /** + * The DeleteFolder action deletes folders in the provided location + */ + DELETE_FOLDER = 'DeleteFolder', + + /** + * The ExecuteBash action runs bash scripts with inline bash commands + */ + EXECUTE_BASH = 'ExecuteBash', + + /** + * The ExecuteBinary action runs a provided binary executable + */ + EXECUTE_BINARY = 'ExecuteBinary', + + /** + * The ExecuteDocument action allows running other component documents from within a given component + */ + EXECUTE_DOCUMENT = 'ExecuteDocument', + + /** + * The ExecutePowershell action runs PowerShell scripts with inline PowerShell commands + */ + EXECUTE_POWERSHELL = 'ExecutePowerShell', + + /** + * The InstallMSI action runs a Windows application with the provided MSI file + */ + INSTALL_MSI = 'InstallMSI', + + /** + * The ListFiles action lists files in the provided folder + */ + LIST_FILES = 'ListFiles', + + /** + * The MoveFile action moves files from a source to a destination + */ + MOVE_FILE = 'MoveFile', + + /** + * The MoveFolder action moves folders from a source to a destination + */ + MOVE_FOLDER = 'MoveFolder', + + /** + * The ReadFile action reads the content of a text file + */ + READ_FILE = 'ReadFile', + + /** + * The Reboot action reboots the instance + */ + REBOOT = 'Reboot', + + /** + * The SetFileEncoding action modifies the encoding property of an existing file + */ + SET_FILE_ENCODING = 'SetFileEncoding', + + /** + * The SetFileOwner action modifies the owner and group ownership properties of an existing file + */ + SET_FILE_OWNER = 'SetFileOwner', + + /** + * The SetFolderOwner action recursively modifies the owner and group ownership properties of an existing folder + */ + SET_FOLDER_OWNER = 'SetFolderOwner', + + /** + * The SetFilePermissions action modifies the permission of an existing file + */ + SET_FILE_PERMISSIONS = 'SetFilePermissions', + + /** + * The SetFolderPermissions action recursively modifies the permissions of an existing folder and all of its subfiles + * and subfolders + */ + SET_FOLDER_PERMISSIONS = 'SetFolderPermissions', + + /** + * The SetRegistry action sets the value for the specified Windows registry key + */ + SET_REGISTRY = 'SetRegistry', + + /** + * The S3Download action downloads an Amazon S3 object/folder to a local destination + */ + S3_DOWNLOAD = 'S3Download', + + /** + * The S3Upload action uploads a file or folder to an Amazon S3 location + */ + S3_UPLOAD = 'S3Upload', + + /** + * The UninstallMSI action removes a Windows application using an MSI file + */ + UNINSTALL_MSI = 'UninstallMSI', + + /** + * The UpdateOS action installs OS updates + */ + UPDATE_OS = 'UpdateOS', + + /** + * The WebDownload action downloads files from a URL to a local destination + */ + WEB_DOWNLOAD = 'WebDownload', +} + +/** + * Specifies what the step should do in case of failure + */ +export enum ComponentOnFailure { + /** + * Fails the step and document execution + */ + ABORT = 'Abort', + + /** + * Fails the step and proceeds to execute the next step in the document + */ + CONTINUE = 'Continue', + + /** + * Ignores the step and proceeds to execute the next step in the document + */ + IGNORE = 'Ignore', +} + +/** + * The parameter type in a component document + */ +export enum ComponentParameterType { + /** + * Indicates the parameter value is a string + */ + STRING = 'string', +} + +/** + * The phases of a component document + */ +export enum ComponentPhaseName { + /** + * Build phase of the component. This phase is run during the BUILDING phase of the image build. + */ + BUILD = 'build', + + /** + * Test phase of the component, executed directly on the instance which is used to build the container image. This + * phase is run during the TESTING phase of the image build. + */ + CONTAINER_HOST_TEST = 'container-host-test', + + /** + * Test phase of the component. This phase is run during the TESTING phase of the image build. + */ + TEST = 'test', + + /** + * Validate phase of the component. This phase is run during the BUILDING phase of the image build, after the build + * step of the component is executed. + */ + VALIDATE = 'validate', +} + +/** + * The schema version of the component + */ +export enum ComponentSchemaVersion { + /** + * Schema version 1.0 for the component document + */ + V1_0 = '1.0', +} + +/** + * Represents the inputs for a step in the component document + */ +export class ComponentStepInputs { + /** + * Creates the input value from an object, for the component step + * + * @param inputsObject The object containing the input values + */ + public static fromObject(inputsObject: { [key: string]: any }): ComponentStepInputs { + return new ComponentStepInputs(inputsObject); + } + + /** + * Creates the input value from a list of input objects, for the component step + * + * @param inputsObjectList The list of objects containing the input values + */ + public static fromList(inputsObjectList: { [key: string]: any }[]): ComponentStepInputs { + return new ComponentStepInputs(inputsObjectList); + } + + /** + * The rendered input value + */ + public readonly inputs: any; + + protected constructor(input: any) { + this.inputs = input; + } +} + +/** + * Represents an `if` condition in the component document + */ +export class ComponentStepIfCondition { + /** + * Creates the `if` value from an object, for the component step + * + * @param ifObject The object containing the `if` condition + */ + public static fromObject(ifObject: { [key: string]: any }): ComponentStepIfCondition { + return new ComponentStepIfCondition(ifObject); + } + + /** + * The rendered input value + */ + public readonly ifCondition: any; + + protected constructor(ifCondition: any) { + this.ifCondition = ifCondition; + } +} + +/** + * Helper class for referencing and uploading component data + */ +export abstract class ComponentData { + /** + * Uploads component data from a local file to S3 to use as the component data + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param path The local path to the component data file + * @param options S3 asset upload options + */ + public static fromAsset( + scope: Construct, + id: string, + path: string, + options: s3assets.AssetOptions = {}, + ): S3ComponentData { + const asset = new s3assets.Asset(scope, id, { ...options, path }); + return new S3ComponentDataFromAsset(asset); + } + + /** + * References component data from a pre-existing S3 object + * + * @param bucket The S3 bucket where the component data is stored + * @param key The S3 key of the component data file + */ + public static fromS3(bucket: s3.IBucket, key: string): S3ComponentData { + return new S3ComponentDataFromBucketKey(bucket, key); + } + + /** + * Uses an inline JSON object as the component data + * + * @param data An inline JSON object representing the component data + */ + public static fromJsonObject(data: { [key: string]: any }): ComponentData { + const inlineData = yaml.stringify(data, { indent: 2 }); + return new InlineComponentData(inlineData); + } + + /** + * Uses an inline JSON object as the component data, using the ComponentDocument interface + * + * @param data An inline JSON object representing the component data + */ + public static fromComponentDocumentJsonObject(data: ComponentDocument): ComponentData { + const { name, description, schemaVersion, constants, parameters, phases } = data; + return this.fromJsonObject({ + ...(name !== undefined && { name }), + ...(description !== undefined && { description }), + schemaVersion: schemaVersion, + ...(constants !== undefined && { + constants: Object.entries(constants).map(([constantName, value]) => ({ + [constantName]: { type: value.type, value: value.value }, + })), + }), + ...(parameters !== undefined && { + parameters: Object.entries(parameters).map(([parameterName, value]) => ({ [parameterName]: value })), + }), + phases: phases.map((phase) => ({ + name: phase.name, + steps: phase.steps.map((step) => ({ + name: step.name, + action: step.action, + ...(step.onFailure !== undefined && { onFailure: step.onFailure }), + ...(step.timeout !== undefined && { timeoutSeconds: step.timeout.toSeconds() }), + ...(step.if !== undefined && { if: step.if.ifCondition }), + ...(step.loop !== undefined && { loop: step.loop }), + inputs: step.inputs.inputs, + })), + })), + }); + } + + /** + * Uses an inline JSON/YAML string as the component data + * + * @param data An inline JSON/YAML string representing the component data + */ + public static fromInline(data: string): ComponentData { + return new InlineComponentData(data); + } + + /** + * Indicates that the provided component data is an S3 reference + */ + abstract readonly isS3Reference: boolean; + + /** + * The resulting inline string or S3 URL which references the component data + */ + public readonly value: string; + + protected constructor(value: string) { + this.value = value; + } +} + +/** + * Helper class for S3-based component data references, containing additional permission grant methods on the S3 object + */ +export abstract class S3ComponentData extends ComponentData { + public readonly isS3Reference = true; + + protected readonly bucket: s3.IBucket; + protected readonly key: string; + + protected constructor(bucket: s3.IBucket, key: string) { + super(bucket.s3UrlForObject(key)); + + this.bucket = bucket; + this.key = key; + } + + /** + * Grant put permissions to the given grantee for the component data in S3 + * + * @param grantee The principal + */ + public grantPut(grantee: iam.IGrantable): iam.Grant { + return this.bucket.grantPut(grantee, this.key); + } + + /** + * Grant read permissions to the given grantee for the component data in S3 + * + * @param grantee The principal + */ + public grantRead(grantee: iam.IGrantable): iam.Grant { + return this.bucket.grantRead(grantee, this.key); + } +} + +class InlineComponentData extends ComponentData { + public readonly isS3Reference = false; + + public constructor(data: string) { + super(data); + } +} + +class S3ComponentDataFromBucketKey extends S3ComponentData { + public constructor(bucket: s3.IBucket, key: string) { + super(bucket, key); + } +} + +class S3ComponentDataFromAsset extends S3ComponentData { + public constructor(asset: s3assets.Asset) { + super(asset.bucket, asset.s3ObjectKey); + } +} + +/** + * Helper class for working with AWS-managed components + */ +export abstract class AwsManagedComponent { + /** + * Imports the AWS CLI v2 AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static awsCliV2(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'awsCliV2', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'aws-cli-version-2-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'aws-cli-version-2-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports the hello world AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static helloWorld(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'helloWorld', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'hello-world-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'hello-world-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports the Python 3 AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static python3(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'python3', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'python-3-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'python-3-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports the reboot AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static reboot(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'reboot', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'reboot-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'reboot-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports the STIG hardening AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + * + * @see https://docs.aws.amazon.com/imagebuilder/latest/userguide/ib-stig.html + */ + public static stigBuild(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'stigBuild', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'stig-build-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'stig-build-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports the OS update AWS-managed component + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static updateOS(scope: Construct, id: string, attrs: AwsManagedComponentAttributes): IComponent { + this.validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component: 'updateOS', + allowedPlatforms: [Platform.LINUX, Platform.WINDOWS], + }); + + if (attrs.platform === Platform.WINDOWS) { + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'update-windows', + componentVersion: attrs.componentVersion, + }); + } + + return this.fromAwsManagedComponentAttributes(scope, id, { + componentName: 'update-linux', + componentVersion: attrs.componentVersion, + }); + } + + /** + * Imports an AWS-managed component from its attributes + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static fromAwsManagedComponentAttributes( + scope: Construct, + id: string, + attrs: AwsManagedComponentAttributes, + ): IComponent { + if (attrs.platform !== undefined) { + throw new cdk.ValidationError( + 'platform can only be used with pre-defined AWS-managed component methods, such as updateOS', + scope, + ); + } + + if (attrs.componentName === undefined) { + throw new cdk.ValidationError('an AWS-managed component name is required', scope); + } + + return Component.fromComponentArn( + scope, + id, + cdk.Stack.of(scope).formatArn({ + service: 'imagebuilder', + account: 'aws', + resource: 'component', + resourceName: `${attrs.componentName}/${attrs.componentVersion ?? LATEST_VERSION}`, + }), + ); + } + /** + * Imports an AWS-managed component from its name + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param awsManagedComponentName - The name of the AWS-managed component + */ + public static fromAwsManagedComponentName(scope: Construct, id: string, awsManagedComponentName: string): IComponent { + return this.fromAwsManagedComponentAttributes(scope, id, { componentName: awsManagedComponentName }); + } + + private static validatePredefinedManagedComponentMethodAttributes({ + scope, + attrs, + component, + allowedPlatforms, + }: { + scope: Construct; + component: string; + attrs: AwsManagedComponentAttributes; + allowedPlatforms: Platform[]; + }) { + if (attrs.componentName !== undefined) { + throw new cdk.ValidationError(`a name is not allowed for ${component}`, scope); + } + + if (attrs.platform === undefined) { + throw new cdk.ValidationError(`a platform is required for ${component}`, scope); + } + + if (cdk.Token.isUnresolved(attrs.platform)) { + throw new cdk.ValidationError(`platform cannot be a token for ${component}`, scope); + } + + if (!allowedPlatforms.includes(attrs.platform)) { + throw new cdk.ValidationError(`${attrs.platform} is not a supported platform for ${component}`, scope); + } + } +} + +/** + * Helper class for working with AWS Marketplace components + */ +export class AwsMarketplaceComponent { + /** + * Imports an AWS Marketplace component from its attributes + * + * @param scope The construct scope + * @param id Identifier of the construct + * @param attrs The AWS-managed component attributes + */ + public static fromAwsMarketplaceComponentAttributes( + scope: Construct, + id: string, + attrs: AwsMarketplaceComponentAttributes, + ): IComponent { + return Component.fromComponentArn( + scope, + id, + cdk.Stack.of(scope).formatArn({ + service: 'imagebuilder', + account: 'aws-marketplace', + resource: 'component', + resourceName: `${attrs.componentName}-${attrs.marketplaceProductId}/${attrs.componentVersion ?? LATEST_VERSION}`, + }), + ); + } +} + +/** + * A new or imported Component + */ +abstract class ComponentBase extends cdk.Resource implements IComponent { + /** + * The ARN of the component + */ + abstract readonly componentArn: string; + /** + * The name of the component + */ + abstract readonly componentName: string; + /** + * The version of the component + */ + abstract readonly componentVersion: string; + + /** + * Grant custom actions to the given grantee for the component + * + * @param grantee The principal + * @param actions The list of actions + */ + public grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant { + return iam.Grant.addToPrincipal({ + grantee, + actions, + resourceArns: [this.componentArn], + scope: this, + }); + } + + /** + * Grant read permissions to the given grantee for the component + * + * @param grantee The principal + */ + public grantRead(grantee: iam.IGrantable): iam.Grant { + return this.grant(grantee, 'imagebuilder:GetComponent'); + } +} + +/** + * Represents an EC2 Image Builder Component. + * + * @see https://docs.aws.amazon.com/imagebuilder/latest/userguide/manage-components.html + */ +@propertyInjectable +export class Component extends ComponentBase { + /** Uniquely identifies this class. */ + public static readonly PROPERTY_INJECTION_ID: string = '@aws-cdk.aws-imagebuilder-alpha.Component'; + + /** + * Import an existing component given its ARN. + */ + public static fromComponentArn(scope: Construct, id: string, componentArn: string): IComponent { + return this.fromComponentAttributes(scope, id, { componentArn }); + } + + /** + * Import an existing component given its name. The provided name must be normalized by converting all alphabetical + * characters to lowercase, and replacing all spaces and underscores with hyphens. + */ + public static fromComponentName(scope: Construct, id: string, componentName: string): IComponent { + return this.fromComponentAttributes(scope, id, { componentName }); + } + + /** + * Import an existing component by providing its attributes. If the component name is provided as an attribute, it + * must be normalized by converting all alphabetical characters to lowercase, and replacing all spaces and underscores + * with hyphens. + */ + public static fromComponentAttributes(scope: Construct, id: string, attrs: ComponentAttributes): IComponent { + if (attrs.componentArn && (attrs.componentName || attrs.componentVersion)) { + throw new cdk.ValidationError( + 'a componentName or componentVersion cannot be provided when a componentArn is provided', + scope, + ); + } + + if (!attrs.componentArn && !attrs.componentName) { + throw new cdk.ValidationError('either componentArn or componentName is required', scope); + } + + const componentArn = + attrs.componentArn ?? + cdk.Stack.of(scope).formatArn({ + service: 'imagebuilder', + resource: 'component', + resourceName: `${attrs.componentName}/${attrs.componentVersion ?? LATEST_VERSION}`, + }); + + const [componentName, componentVersion] = (() => { + if (attrs.componentName) { + return [attrs.componentName, attrs.componentVersion ?? LATEST_VERSION]; + } + + const componentNameVersion = cdk.Stack.of(scope).splitArn( + componentArn, + cdk.ArnFormat.SLASH_RESOURCE_NAME, + ).resourceName!; + + const componentNameVersionSplit = cdk.Fn.split('/', componentNameVersion); + return [cdk.Fn.select(0, componentNameVersionSplit), cdk.Fn.select(1, componentNameVersionSplit)]; + })(); + + class Import extends ComponentBase { + public readonly componentArn = componentArn; + public readonly componentName = componentName; + public readonly componentVersion = componentVersion; + } + + return new Import(scope, id); + } + + /** + * Return whether the given object is a Component. + */ + public static isComponent(x: any): x is Component { + return x !== null && typeof x === 'object' && COMPONENT_SYMBOL in x; + } + + /** + * The ARN of the component + */ + public readonly componentArn: string; + + /** + * The name of the component + */ + public readonly componentName: string; + + /** + * The version of the component + */ + public readonly componentVersion: string; + + /** + * Whether the component is encrypted + */ + public readonly encrypted: boolean; + + /** + * The type of the component + * + * @attribute + */ + public readonly componentType: string; + + protected readonly kmsKey?: kms.IKey; + + public constructor(scope: Construct, id: string, props: ComponentProps) { + super(scope, id, { + physicalName: + props.componentName ?? + cdk.Lazy.string({ + produce: () => + cdk.Names.uniqueResourceName(this, { + maxLength: 128, + separator: '-', + allowedSpecialCharacters: '-', + }).toLowerCase(), // Enforce lowercase for the auto-generated fallback + }), + }); + + Object.defineProperty(this, COMPONENT_SYMBOL, { value: true }); + + this.validateComponentName(); + + props.supportedOsVersions?.forEach((osVersion) => { + if (osVersion.platform !== props.platform) { + throw new cdk.ValidationError( + `os version ${osVersion.osVersion} is not compatible with platform ${props.platform}`, + this, + ); + } + }); + + const componentVersion = props.componentVersion ?? '1.0.0'; + const supportedOsVersions = props.supportedOsVersions?.filter((osVersion) => osVersion.osVersion !== undefined); + + const component = new CfnComponent(this, 'Resource', { + name: this.physicalName, + version: componentVersion, + changeDescription: props.changeDescription, + description: props.description, + platform: props.platform, + kmsKeyId: props.kmsKey?.keyArn, + tags: props.tags, + ...(props.data.isS3Reference ? { uri: props.data.value } : { data: props.data.value }), + ...(supportedOsVersions?.length && { + supportedOsVersions: supportedOsVersions.map((osVersion) => osVersion.osVersion!), + }), + }); + + this.componentName = this.getResourceNameAttribute(component.attrName); + this.componentArn = this.getResourceArnAttribute(component.attrArn, { + service: 'imagebuilder', + resource: 'component', + resourceName: `${this.physicalName}/${componentVersion}`, + }); + this.componentVersion = componentVersion; + this.encrypted = true; // Components are always encrypted + this.componentType = component.attrType; + this.kmsKey = props.kmsKey; + } + + private validateComponentName() { + if (cdk.Token.isUnresolved(this.physicalName)) { + return; // Cannot validate unresolved tokens, given their actual value is rendered at deployment time + } + + if (this.physicalName.length > 128) { + throw new cdk.ValidationError( + `the componentName cannot be longer than 128 characters, got: '${this.physicalName}'`, + this, + ); + } + + if (this.physicalName.includes(' ')) { + throw new cdk.ValidationError(`the componentName cannot contain spaces, got: '${this.physicalName}'`, this); + } + + if (this.physicalName.includes('_')) { + throw new cdk.ValidationError(`the componentName cannot contain underscores, got: '${this.physicalName}'`, this); + } + + if (this.physicalName !== this.physicalName.toLowerCase()) { + throw new cdk.ValidationError(`the componentName must be lowercase, got: '${this.physicalName}'`, this); + } + } +} diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/lib/index.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/index.ts index 97cf3cbca1ef6..8ce5becc539dd 100644 --- a/packages/@aws-cdk/aws-imagebuilder-alpha/lib/index.ts +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/index.ts @@ -1,4 +1,7 @@ // AWS::ImageBuilder CloudFormation Resources: +export * from './component'; export * from './distribution-configuration'; export * from './infrastructure-configuration'; + +export * from './os-version'; diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/lib/os-version.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/os-version.ts new file mode 100644 index 0000000000000..070f2684000c8 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/lib/os-version.ts @@ -0,0 +1,156 @@ +/** + * Represents a platform for an EC2 Image Builder image + */ +export enum Platform { + /** + * Platform for Linux + */ + LINUX = 'Linux', + + /** + * Platform for Windows + */ + WINDOWS = 'Windows', + + /** + * Platform for macOS + */ + MAC_OS = 'macOS', +} + +/** + * Represents an OS version for an EC2 Image Builder image + */ +export class OSVersion { + /** + * OS version for all Linux images + */ + public static readonly LINUX = new OSVersion(Platform.LINUX); + + /** + * OS version for all macOS images + */ + public static readonly MAC_OS = new OSVersion(Platform.MAC_OS); + + /** + * OS version for all Windows images + */ + public static readonly WINDOWS = new OSVersion(Platform.WINDOWS); + + /** + * OS version for all Amazon Linux images + */ + public static readonly AMAZON_LINUX = new OSVersion(Platform.LINUX, 'Amazon Linux'); + + /** + * OS version for Amazon Linux 2 + */ + public static readonly AMAZON_LINUX_2 = new OSVersion(Platform.LINUX, 'Amazon Linux 2'); + + /** + * OS version for Amazon Linux 2023 + */ + public static readonly AMAZON_LINUX_2023 = new OSVersion(Platform.LINUX, 'Amazon Linux 2023'); + + /** + * OS version for macOS 14 + */ + public static readonly MAC_OS_14 = new OSVersion(Platform.MAC_OS, 'macOS 14'); + + /** + * OS version for macOS 15 + */ + public static readonly MAC_OS_15 = new OSVersion(Platform.MAC_OS, 'macOS 15'); + + /** + * OS version for all Red Hat Enterprise Linux images + */ + public static readonly REDHAT_ENTERPRISE_LINUX = new OSVersion(Platform.LINUX, 'Red Hat Enterprise Linux'); + + /** + * OS version for Red Hat Enterprise Linux 8 + */ + public static readonly REDHAT_ENTERPRISE_LINUX_8 = new OSVersion(Platform.LINUX, 'Red Hat Enterprise Linux 8'); + + /** + * OS version for Red Hat Enterprise Linux 9 + */ + public static readonly REDHAT_ENTERPRISE_LINUX_9 = new OSVersion(Platform.LINUX, 'Red Hat Enterprise Linux 9'); + + /** + * OS version for Red Hat Enterprise Linux 10 + */ + public static readonly REDHAT_ENTERPRISE_LINUX_10 = new OSVersion(Platform.LINUX, 'Red Hat Enterprise Linux 10'); + + /** + * OS version for all SLES images + */ + public static readonly SLES = new OSVersion(Platform.LINUX, 'SLES'); + + /** + * OS version for SLES 15 + */ + public static readonly SLES_15 = new OSVersion(Platform.LINUX, 'SLES 15'); + + /** + * OS version for all Ubuntu images + */ + public static readonly UBUNTU = new OSVersion(Platform.LINUX, 'Ubuntu'); + + /** + * OS version for Ubuntu 22.04 + */ + public static readonly UBUNTU_22_04 = new OSVersion(Platform.LINUX, 'Ubuntu 22'); + + /** + * OS version for Ubuntu 24.04 + */ + public static readonly UBUNTU_24_04 = new OSVersion(Platform.LINUX, 'Ubuntu 24'); + + /** + * OS version for all Windows server images + */ + public static readonly WINDOWS_SERVER = new OSVersion(Platform.WINDOWS, 'Microsoft Windows Server'); + + /** + * OS version for Windows Server 2016 + */ + public static readonly WINDOWS_SERVER_2016 = new OSVersion(Platform.WINDOWS, 'Microsoft Windows Server 2016'); + /** + * OS version for Windows Server 2019 + */ + public static readonly WINDOWS_SERVER_2019 = new OSVersion(Platform.WINDOWS, 'Microsoft Windows Server 2019'); + /** + * OS version for Windows Server 2022 + */ + public static readonly WINDOWS_SERVER_2022 = new OSVersion(Platform.WINDOWS, 'Microsoft Windows Server 2022'); + /** + * OS version for Windows Server 2025 + */ + public static readonly WINDOWS_SERVER_2025 = new OSVersion(Platform.WINDOWS, 'Microsoft Windows Server 2025'); + + /** + * Constructs an OS version with a custom name + * + * @param platform The platform of the OS version + * @param osVersion The custom OS version to use + */ + public static custom(platform: Platform, osVersion?: string) { + return new OSVersion(platform, osVersion); + } + + /** + * The Platform of the OS version + */ + public readonly platform: Platform; + + /** + * The OS version name + */ + public readonly osVersion?: string; + + protected constructor(platform: Platform, osVersion?: string) { + this.platform = platform; + this.osVersion = osVersion; + } +} diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/assets/component-data.yaml b/packages/@aws-cdk/aws-imagebuilder-alpha/test/assets/component-data.yaml new file mode 100644 index 0000000000000..5dde0514b5313 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/assets/component-data.yaml @@ -0,0 +1,28 @@ +name: HelloWorldBuildDocument +description: This is hello world build document. +schemaVersion: 1.0 + +phases: + - name: build + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Build." + + - name: validate + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Validate." + + - name: test + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Test." diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/component.test.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/component.test.ts new file mode 100644 index 0000000000000..4058ad2e008e5 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/component.test.ts @@ -0,0 +1,956 @@ +import * as path from 'path'; +import * as cdk from 'aws-cdk-lib'; +import { Match, Template } from 'aws-cdk-lib/assertions'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as kms from 'aws-cdk-lib/aws-kms'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import { + AwsManagedComponent, + AwsMarketplaceComponent, + Component, + ComponentAction, + ComponentConstantValue, + ComponentData, + ComponentOnFailure, + ComponentParameterType, + ComponentPhaseName, + ComponentSchemaVersion, + ComponentStepInputs, + OSVersion, + Platform, +} from '../lib'; + +describe('Component', () => { + let app: cdk.App; + let stack: cdk.Stack; + + beforeEach(() => { + app = new cdk.App(); + stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-east-1', account: '123456789012' } }); + }); + + test('imported by name', () => { + const component = Component.fromComponentName(stack, 'Component', 'imported-component-by-name'); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:123456789012:component/imported-component-by-name/x.x.x', + ], + ], + }); + expect(component.componentName).toEqual('imported-component-by-name'); + expect(component.componentVersion).toEqual('x.x.x'); + }); + + test('imported by name as an unresolved token', () => { + const component = Component.fromComponentName(stack, 'Component', `test-component-${stack.partition}`); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:123456789012:component/test-component-', + { Ref: 'AWS::Partition' }, + '/x.x.x', + ], + ], + }); + expect(stack.resolve(component.componentName)).toEqual({ + 'Fn::Join': ['', ['test-component-', { Ref: 'AWS::Partition' }]], + }); + expect(component.componentVersion).toEqual('x.x.x'); + }); + + test('imported by arn', () => { + const component = Component.fromComponentArn( + stack, + 'Component', + 'arn:aws:imagebuilder:us-east-1:123456789012:component/imported-component-by-arn/1.2.3/4', + ); + + expect(component.componentArn).toEqual( + 'arn:aws:imagebuilder:us-east-1:123456789012:component/imported-component-by-arn/1.2.3/4', + ); + expect(component.componentName).toEqual('imported-component-by-arn'); + expect(component.componentVersion).toEqual('1.2.3'); + }); + + test('imported by arn as an unresolved token', () => { + const component = Component.fromComponentArn( + stack, + 'Component', + `arn:aws:imagebuilder:us-east-1:123456789012:component/imported-component-by-arn-${stack.partition}/1.2.3/4`, + ); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:aws:imagebuilder:us-east-1:123456789012:component/imported-component-by-arn-', + { Ref: 'AWS::Partition' }, + '/1.2.3/4', + ], + ], + }); + expect(stack.resolve(component.componentName)).toEqual({ + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '/', + { 'Fn::Join': ['', ['imported-component-by-arn-', { Ref: 'AWS::Partition' }, '/1.2.3/4']] }, + ], + }, + ], + }); + expect(stack.resolve(component.componentVersion)).toEqual({ + 'Fn::Select': [ + 1, + { + 'Fn::Split': [ + '/', + { + 'Fn::Join': ['', ['imported-component-by-arn-', { Ref: 'AWS::Partition' }, '/1.2.3/4']], + }, + ], + }, + ], + }); + }); + + test('imported by attributes', () => { + const component = Component.fromComponentAttributes(stack, 'Component', { + componentName: 'imported-component-by-attributes', + componentVersion: '1.2.3', + }); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:123456789012:component/imported-component-by-attributes/1.2.3', + ], + ], + }); + expect(component.componentName).toEqual('imported-component-by-attributes'); + expect(component.componentVersion).toEqual('1.2.3'); + }); + + test('AWS-managed component import by name', () => { + const component = AwsManagedComponent.fromAwsManagedComponentName( + stack, + 'Component', + 'amazon-cloudwatch-agent-linux', + ); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:aws:component/amazon-cloudwatch-agent-linux/x.x.x', + ], + ], + }); + expect(component.componentName).toEqual('amazon-cloudwatch-agent-linux'); + expect(component.componentVersion).toEqual('x.x.x'); + }); + + test('AWS-managed component import by attributes', () => { + const component = AwsManagedComponent.fromAwsManagedComponentAttributes(stack, 'Component', { + componentName: 'amazon-cloudwatch-agent-linux', + componentVersion: 'x.x.x', + }); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:aws:component/amazon-cloudwatch-agent-linux/x.x.x', + ], + ], + }); + expect(component.componentName).toEqual('amazon-cloudwatch-agent-linux'); + expect(component.componentVersion).toEqual('x.x.x'); + }); + + test('AWS-managed component pre-defined method import', () => { + const awsCliV2Linux = AwsManagedComponent.awsCliV2(stack, 'AwsCliV2Linux-Component', { platform: Platform.LINUX }); + const awsCliV2Windows = AwsManagedComponent.awsCliV2(stack, 'AwsCliV2Windows-Component', { + platform: Platform.WINDOWS, + }); + const helloWorldLinux = AwsManagedComponent.helloWorld(stack, 'HelloWorldLinux-Component', { + platform: Platform.LINUX, + }); + const helloWorldWindows = AwsManagedComponent.helloWorld(stack, 'HelloWorldWindows-Component', { + platform: Platform.WINDOWS, + }); + const python3Linux = AwsManagedComponent.python3(stack, 'Python3Linux-Component', { platform: Platform.LINUX }); + const python3Windows = AwsManagedComponent.python3(stack, 'Python3Windows-Component', { + platform: Platform.WINDOWS, + }); + const rebootLinux = AwsManagedComponent.reboot(stack, 'RebootLinux-Component', { platform: Platform.LINUX }); + const rebootWindows = AwsManagedComponent.reboot(stack, 'RebootWindows-Component', { platform: Platform.WINDOWS }); + const stigBuildLinux = AwsManagedComponent.stigBuild(stack, 'StigBuildLinux-Component', { + platform: Platform.LINUX, + }); + const stigBuildWindows = AwsManagedComponent.stigBuild(stack, 'StigBuildWindows-Component', { + platform: Platform.WINDOWS, + }); + const updateLinux = AwsManagedComponent.updateOS(stack, 'UpdateLinux-Component', { platform: Platform.LINUX }); + const updateWindows = AwsManagedComponent.updateOS(stack, 'UpdateWindows-Component', { + platform: Platform.WINDOWS, + }); + + const expectedComponentArn = (componentName: string) => ({ + 'Fn::Join': [ + '', + ['arn:', { Ref: 'AWS::Partition' }, `:imagebuilder:us-east-1:aws:component/${componentName}/x.x.x`], + ], + }); + + expect(stack.resolve(awsCliV2Linux.componentArn)).toEqual(expectedComponentArn('aws-cli-version-2-linux')); + expect(stack.resolve(awsCliV2Windows.componentArn)).toEqual(expectedComponentArn('aws-cli-version-2-windows')); + expect(stack.resolve(helloWorldLinux.componentArn)).toEqual(expectedComponentArn('hello-world-linux')); + expect(stack.resolve(helloWorldWindows.componentArn)).toEqual(expectedComponentArn('hello-world-windows')); + expect(stack.resolve(python3Linux.componentArn)).toEqual(expectedComponentArn('python-3-linux')); + expect(stack.resolve(python3Windows.componentArn)).toEqual(expectedComponentArn('python-3-windows')); + expect(stack.resolve(rebootLinux.componentArn)).toEqual(expectedComponentArn('reboot-linux')); + expect(stack.resolve(rebootWindows.componentArn)).toEqual(expectedComponentArn('reboot-windows')); + expect(stack.resolve(stigBuildLinux.componentArn)).toEqual(expectedComponentArn('stig-build-linux')); + expect(stack.resolve(stigBuildWindows.componentArn)).toEqual(expectedComponentArn('stig-build-windows')); + expect(stack.resolve(updateLinux.componentArn)).toEqual(expectedComponentArn('update-linux')); + expect(stack.resolve(updateWindows.componentArn)).toEqual(expectedComponentArn('update-windows')); + }); + + test('AWS Marketplace component import by required attributes', () => { + const component = AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(stack, 'Component', { + componentName: 'marketplace-component', + componentVersion: '1.x.x', + marketplaceProductId: 'marketplace-product-id', + }); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:aws-marketplace:component/marketplace-component-marketplace-product-id/1.x.x', + ], + ], + }); + expect(component.componentName).toEqual('marketplace-component-marketplace-product-id'); + expect(component.componentVersion).toEqual('1.x.x'); + }); + + test('AWS Marketplace component import by all attributes', () => { + const component = AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(stack, 'Component', { + componentName: 'marketplace-component', + marketplaceProductId: 'marketplace-product-id', + }); + + expect(stack.resolve(component.componentArn)).toEqual({ + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':imagebuilder:us-east-1:aws-marketplace:component/marketplace-component-marketplace-product-id/x.x.x', + ], + ], + }); + expect(component.componentName).toEqual('marketplace-component-marketplace-product-id'); + expect(component.componentVersion).toEqual('x.x.x'); + }); + + test('with all parameters', () => { + const component = new Component(stack, 'Component', { + componentName: 'test-component', + componentVersion: '1.0.0', + description: 'This is a test component', + changeDescription: 'This is a change description', + platform: Platform.LINUX, + kmsKey: kms.Key.fromKeyArn( + stack, + 'ComponentKey', + stack.formatArn({ service: 'kms', resource: 'key', resourceName: '1234abcd-12ab-34cd-56ef-1234567890ab' }), + ), + supportedOsVersions: [OSVersion.AMAZON_LINUX, OSVersion.custom(Platform.LINUX, 'Custom OS')], + data: ComponentData.fromComponentDocumentJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + constants: { + Constant1: ComponentConstantValue.fromString('Constant1Value'), + Constant2: ComponentConstantValue.fromString('Constant2Value'), + }, + parameters: { + Parameter1: { type: ComponentParameterType.STRING, default: 'Parameter1Value' }, + Parameter2: { type: ComponentParameterType.STRING, default: 'Parameter2Value' }, + }, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + name: 'hello-world-build', + action: ComponentAction.EXECUTE_BASH, + onFailure: ComponentOnFailure.CONTINUE, + timeout: cdk.Duration.seconds(720), + loop: { + name: 'scope', + forEach: ['world', 'universe'], + }, + inputs: ComponentStepInputs.fromObject({ + commands: ['echo "Hello {{ scope.value }}!"'], + }), + }, + ], + }, + { + name: ComponentPhaseName.VALIDATE, + steps: [ + { + name: 'hello-world-validate', + action: ComponentAction.EXECUTE_BASH, + loop: { + name: 'scope', + for: { + start: 0, + end: 10, + updateBy: 1, + }, + }, + inputs: ComponentStepInputs.fromObject({ + commands: ['echo "Hello {{ scope.index }} validate!"'], + }), + }, + ], + }, + { + name: ComponentPhaseName.TEST, + steps: [ + { + name: 'hello-world-download-test', + action: ComponentAction.WEB_DOWNLOAD, + inputs: ComponentStepInputs.fromList([ + { source: 'https://download.com/package.zip', destination: '/tmp/package.zip' }, + ]), + }, + ], + }, + ], + }), + }); + + expect(Component.isComponent(component as unknown)).toBeTruthy(); + expect(Component.isComponent('Component')).toBeFalsy(); + + Template.fromStack(stack).templateMatches({ + Resources: { + Component0EED0119: Match.objectEquals({ + Type: 'AWS::ImageBuilder::Component', + Properties: { + Name: 'test-component', + Version: '1.0.0', + Description: 'This is a test component', + ChangeDescription: 'This is a change description', + Platform: 'Linux', + SupportedOsVersions: ['Amazon Linux', 'Custom OS'], + KmsKeyId: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab', + ], + ], + }, + Data: `name: test-component +schemaVersion: "1.0" +constants: + - Constant1: + type: string + value: Constant1Value + - Constant2: + type: string + value: Constant2Value +parameters: + - Parameter1: + type: string + default: Parameter1Value + - Parameter2: + type: string + default: Parameter2Value +phases: + - name: build + steps: + - name: hello-world-build + action: ExecuteBash + onFailure: Continue + timeoutSeconds: 720 + loop: + name: scope + forEach: + - world + - universe + inputs: + commands: + - echo "Hello {{ scope.value }}!" + - name: validate + steps: + - name: hello-world-validate + action: ExecuteBash + loop: + name: scope + for: + start: 0 + end: 10 + updateBy: 1 + inputs: + commands: + - echo "Hello {{ scope.index }} validate!" + - name: test + steps: + - name: hello-world-download-test + action: WebDownload + inputs: + - source: https://download.com/package.zip + destination: /tmp/package.zip +`, + }, + }), + }, + }); + }); + + test('with required parameters', () => { + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + name: 'hello-world-build', + action: ComponentAction.EXECUTE_BASH, + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }); + + Template.fromStack(stack).templateMatches({ + Resources: { + Component0EED0119: Match.objectEquals({ + Type: 'AWS::ImageBuilder::Component', + Properties: { + Name: 'stack-component-33dabf20', + Version: '1.0.0', + Platform: 'Linux', + Data: `name: test-component +schemaVersion: "1.0" +phases: + - name: build + steps: + - name: hello-world-build + action: ExecuteBash + inputs: + commands: + - echo "Hello build!" +`, + }, + }), + }, + }); + }); + + test('with component data as a file asset', () => { + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromAsset(stack, 'ComponentData', path.join(__dirname, 'assets', 'component-data.yaml')), + }); + + Template.fromStack(stack).templateMatches({ + Resources: { + Component0EED0119: Match.objectEquals({ + Type: 'AWS::ImageBuilder::Component', + Properties: { + Name: 'stack-component-33dabf20', + Version: '1.0.0', + Platform: 'Linux', + Uri: 's3://cdk-hnb659fds-assets-123456789012-us-east-1/bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml', + }, + }), + }, + }); + }); + + test('with component data as an S3 location', () => { + const bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'component-bucket-123456789012-us-east-1'); + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromS3(bucket, 'components/component.yaml'), + }); + + Template.fromStack(stack).templateMatches({ + Resources: { + Component0EED0119: Match.objectEquals({ + Type: 'AWS::ImageBuilder::Component', + Properties: { + Name: 'stack-component-33dabf20', + Version: '1.0.0', + Platform: 'Linux', + Uri: 's3://component-bucket-123456789012-us-east-1/components/component.yaml', + }, + }), + }, + }); + }); + + test('with component data as an inline string', () => { + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromInline(`name: test-component +schemaVersion: "1.0" +phases: + - name: build + steps: + - name: hello-world-build + action: ExecuteBash + inputs: + commands: + - echo "Hello build!" +`), + }); + + Template.fromStack(stack).templateMatches({ + Resources: { + Component0EED0119: Match.objectEquals({ + Type: 'AWS::ImageBuilder::Component', + Properties: { + Name: 'stack-component-33dabf20', + Version: '1.0.0', + Platform: 'Linux', + Data: `name: test-component +schemaVersion: "1.0" +phases: + - name: build + steps: + - name: hello-world-build + action: ExecuteBash + inputs: + commands: + - echo "Hello build!" +`, + }, + }), + }, + }); + }); + + test('grants read access to IAM roles', () => { + const component = new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }); + + const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountPrincipal('123456789012') }); + + component.grantRead(role); + + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::IAM::Policy', 1); + template.resourceCountIs('AWS::IAM::Role', 1); + template.resourceCountIs('AWS::ImageBuilder::Component', 1); + expect(Object.keys(template.toJSON().Resources)).toHaveLength(3); + + template.hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::123456789012:root']], + }, + }, + }, + ], + }, + }); + + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Action: 'imagebuilder:GetComponent', + Resource: { + 'Fn::GetAtt': ['Component0EED0119', 'Arn'], + }, + }, + ], + }, + Roles: [Match.anyValue()], + }); + }); + + test('grants permissions to IAM roles', () => { + const component = new Component(stack, 'Component', { + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }); + + const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountPrincipal('123456789012') }); + + component.grant(role, 'imagebuilder:DeleteComponent', 'imagebuilder:GetComponent'); + + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::IAM::Policy', 1); + template.resourceCountIs('AWS::IAM::Role', 1); + template.resourceCountIs('AWS::ImageBuilder::Component', 1); + expect(Object.keys(template.toJSON().Resources)).toHaveLength(3); + + template.hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::123456789012:root']], + }, + }, + }, + ], + }, + }); + + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Action: ['imagebuilder:DeleteComponent', 'imagebuilder:GetComponent'], + Resource: { + 'Fn::GetAtt': ['Component0EED0119', 'Arn'], + }, + }, + ], + }, + Roles: [Match.anyValue()], + }); + }); + + test('grants S3 put permissions on S3 asset to IAM roles', () => { + const bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'component-bucket-123456789012-us-east-1'); + const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountPrincipal('123456789012') }); + const componentData = ComponentData.fromS3(bucket, 'components/component.yaml'); + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: componentData, + }); + + componentData.grantPut(role); + + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::IAM::Policy', 1); + template.resourceCountIs('AWS::IAM::Role', 1); + template.resourceCountIs('AWS::ImageBuilder::Component', 1); + expect(Object.keys(template.toJSON().Resources)).toHaveLength(3); + + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyName: Match.anyValue(), + PolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Action: Match.arrayWith(['s3:PutObject']), + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::component-bucket-123456789012-us-east-1/components/component.yaml', + ], + ], + }, + }, + ], + }, + Roles: [Match.anyValue()], + }); + }); + + test('grants S3 read permissions on S3 asset to IAM roles', () => { + const bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'component-bucket-123456789012-us-east-1'); + const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountPrincipal('123456789012') }); + const componentData = ComponentData.fromS3(bucket, 'components/component.yaml'); + new Component(stack, 'Component', { + platform: Platform.LINUX, + data: componentData, + }); + + componentData.grantRead(role); + + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::IAM::Policy', 1); + template.resourceCountIs('AWS::IAM::Role', 1); + template.resourceCountIs('AWS::ImageBuilder::Component', 1); + expect(Object.keys(template.toJSON().Resources)).toHaveLength(3); + + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyName: Match.anyValue(), + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Allow', + Action: Match.arrayWith(['s3:GetObject*']), + Resource: [ + { + 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':s3:::component-bucket-123456789012-us-east-1']], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::component-bucket-123456789012-us-east-1/components/component.yaml', + ], + ], + }, + ], + }, + ], + }, + Roles: [Match.anyValue()], + }); + }); + + test('throws a validation error when a componentArn and componentName are provided when importing by attributes', () => { + expect(() => + Component.fromComponentAttributes(stack, 'Component', { + componentArn: 'arn:aws:imagebuilder:us-east-1:123456789012:component/imported-component/x.x.x', + componentName: 'imported-component', + }), + ).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when neither a componentArn and componentName are provided when importing by attributes', () => { + expect(() => Component.fromComponentAttributes(stack, 'Component', {})).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when importing an AWS-managed component with the platform attribute', () => { + expect(() => + AwsManagedComponent.fromAwsManagedComponentAttributes(stack, 'Component', { + componentName: 'hello-world-linux', + platform: Platform.LINUX, + }), + ).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when importing an AWS-managed component without the componentName attribute', () => { + expect(() => AwsManagedComponent.fromAwsManagedComponentAttributes(stack, 'Component', {})).toThrow( + cdk.ValidationError, + ); + }); + + test('throws a validation error when importing a pre-defined AWS-managed component without the platform attribute', () => { + expect(() => AwsManagedComponent.helloWorld(stack, 'Component', {})).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when importing a pre-defined AWS-managed component with an unresolved platform attribute', () => { + const platform = new cdk.CfnParameter(stack, 'Platform', { type: 'String' }).valueAsString; + + expect(() => AwsManagedComponent.helloWorld(stack, 'Component', { platform: platform as Platform })).toThrow( + cdk.ValidationError, + ); + }); + + test('throws a validation error when importing a pre-defined AWS-managed component with the componentName attribute', () => { + expect(() => AwsManagedComponent.helloWorld(stack, 'Component', { componentName: 'hello-world-linux' })).toThrow( + cdk.ValidationError, + ); + }); + + test('throws a validation error when importing a pre-defined AWS-managed component with an unsupported platform provided', () => { + expect(() => AwsManagedComponent.helloWorld(stack, 'Component', { platform: Platform.MAC_OS })).toThrow( + cdk.ValidationError, + ); + }); + + test('throws a validation error when the resource name is too long', () => { + expect( + () => + new Component(stack, 'Component', { + componentName: 'a'.repeat(129), + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }), + ).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when the resource name contains spaces', () => { + expect( + () => + new Component(stack, 'Component', { + componentName: 'hello world', + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }), + ).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when the resource name contains underscores', () => { + expect( + () => + new Component(stack, 'Component', { + componentName: 'hello_world', + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }), + ).toThrow(cdk.ValidationError); + }); + + test('throws a validation error when the resource name contains uppercase characters', () => { + expect( + () => + new Component(stack, 'Component', { + componentName: 'HelloWorld', + platform: Platform.LINUX, + data: ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: ComponentSchemaVersion.V1_0, + phases: [ + { + name: ComponentPhaseName.BUILD, + steps: [ + { + action: ComponentAction.EXECUTE_BASH, + name: 'hello-world-build', + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), + }), + ).toThrow(cdk.ValidationError); + }); +}); diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json new file mode 100644 index 0000000000000..ee59271eedeee --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "ComponentTestDefaultTestDeployAssert990A2773 Template", + "source": { + "path": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-d8d86b35": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.assets.json new file mode 100644 index 0000000000000..583f765680eab --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "07c5b8608cbeca83df057729b80bb11c39ff282f8d7166c35a8503bb91a49184": { + "displayName": "aws-cdk-imagebuilder-component-all-parameters Template", + "source": { + "path": "aws-cdk-imagebuilder-component-all-parameters.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-fcbe784b": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "07c5b8608cbeca83df057729b80bb11c39ff282f8d7166c35a8503bb91a49184.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.template.json new file mode 100644 index 0000000000000..783e2c45f093e --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-all-parameters.template.json @@ -0,0 +1,95 @@ +{ + "Resources": { + "ComponentEncryptionKeyAF9A6C9C": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PendingWindowInDays": 7 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "InlineComponent537607D7": { + "Type": "AWS::ImageBuilder::Component", + "Properties": { + "ChangeDescription": "This is a change description", + "Data": "name: test-component\nschemaVersion: \"1.0\"\nconstants:\n - constant:\n type: string\n value: constant value\nparameters:\n - parameter:\n type: string\n description: This is a parameter\n default: default value\nphases:\n - name: build\n steps:\n - name: hello-world-build\n action: ExecuteBash\n onFailure: Continue\n timeoutSeconds: 720\n inputs:\n commands:\n - echo \"Hello build! {{ parameter }} {{ constant }}\"\n - name: validate\n steps:\n - name: hello-world-validate\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello validate!\"\n - name: test\n steps:\n - name: hello-world-test\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello test!\"\n", + "Description": "This is a test component", + "KmsKeyId": { + "Fn::GetAtt": [ + "ComponentEncryptionKeyAF9A6C9C", + "Arn" + ] + }, + "Name": "aws-cdk-imagebuilder-component-all-parameters-inline", + "Platform": "Linux", + "SupportedOsVersions": [ + "Amazon Linux", + "Custom OS" + ], + "Version": "1.0.0" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/cdk.out b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/cdk.out new file mode 100644 index 0000000000000..523a9aac37cbf --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"48.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/integ.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/integ.json new file mode 100644 index 0000000000000..61c523775f3e5 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "48.0.0", + "testCases": { + "ComponentTest/DefaultTest": { + "stacks": [ + "aws-cdk-imagebuilder-component-all-parameters" + ], + "assertionStack": "ComponentTest/DefaultTest/DeployAssert", + "assertionStackName": "ComponentTestDefaultTestDeployAssert990A2773" + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/manifest.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/manifest.json new file mode 100644 index 0000000000000..280147418b03f --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/manifest.json @@ -0,0 +1,627 @@ +{ + "version": "48.0.0", + "artifacts": { + "aws-cdk-imagebuilder-component-all-parameters.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-imagebuilder-component-all-parameters.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-imagebuilder-component-all-parameters": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-imagebuilder-component-all-parameters.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/07c5b8608cbeca83df057729b80bb11c39ff282f8d7166c35a8503bb91a49184.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-imagebuilder-component-all-parameters.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-imagebuilder-component-all-parameters.assets" + ], + "metadata": { + "/aws-cdk-imagebuilder-component-all-parameters/Component-EncryptionKey": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "removalPolicy": "destroy", + "pendingWindow": "*" + } + } + ], + "/aws-cdk-imagebuilder-component-all-parameters/Component-EncryptionKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ComponentEncryptionKeyAF9A6C9C" + } + ], + "/aws-cdk-imagebuilder-component-all-parameters/InlineComponent/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "InlineComponent537607D7", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], + "/aws-cdk-imagebuilder-component-all-parameters/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-imagebuilder-component-all-parameters/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-imagebuilder-component-all-parameters" + }, + "ComponentTestDefaultTestDeployAssert990A2773.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ComponentTestDefaultTestDeployAssert990A2773.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ComponentTestDefaultTestDeployAssert990A2773": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "metadata": { + "/ComponentTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ComponentTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "aws-cdk-lib/feature-flag-report": { + "type": "cdk:feature-flag-report", + "properties": { + "module": "aws-cdk-lib", + "flags": { + "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": { + "userValue": true, + "recommendedValue": true, + "explanation": "Pass signingProfileName to CfnSigningProfile" + }, + "@aws-cdk/core:newStyleStackSynthesis": { + "recommendedValue": true, + "explanation": "Switch to new stack synthesis method which enables CI/CD", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:stackRelativeExports": { + "recommendedValue": true, + "explanation": "Name exports based on the construct paths relative to the stack, rather than the global construct path", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": { + "userValue": true, + "recommendedValue": true, + "explanation": "Disable implicit openListener when custom security groups are provided" + }, + "@aws-cdk/aws-rds:lowercaseDbIdentifier": { + "recommendedValue": true, + "explanation": "Force lowercasing of RDS Cluster names in CDK", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": { + "recommendedValue": true, + "explanation": "Allow adding/removing multiple UsagePlanKeys independently", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeVersionProps": { + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeLayerVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`." + }, + "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": { + "recommendedValue": true, + "explanation": "Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:checkSecretUsage": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this flag to make it impossible to accidentally use SecretValues in unsafe locations" + }, + "@aws-cdk/core:target-partitions": { + "recommendedValue": [ + "aws", + "aws-cn" + ], + "explanation": "What regions to include in lookup tables of environment agnostic stacks" + }, + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": { + "userValue": true, + "recommendedValue": true, + "explanation": "ECS extensions will automatically add an `awslogs` driver if no logging is specified" + }, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to have Launch Templates generated by the `InstanceRequireImdsv2Aspect` use unique names." + }, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": { + "userValue": true, + "recommendedValue": true, + "explanation": "ARN format used by ECS. In the new ARN format, the cluster name is part of the resource ID." + }, + "@aws-cdk/aws-iam:minimizePolicies": { + "userValue": true, + "recommendedValue": true, + "explanation": "Minimize IAM policies by combining Statements" + }, + "@aws-cdk/core:validateSnapshotRemovalPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Error on snapshot removal policies on resources that do not support it." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate key aliases that include the stack name" + }, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to create an S3 bucket policy by default in cases where an AWS service would automatically create the Policy if one does not exist." + }, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict KMS key policy for encrypted Queues a bit more" + }, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make default CloudWatch Role behavior safe for multiple API Gateways in one environment" + }, + "@aws-cdk/core:enablePartitionLiterals": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make ARNs concrete if AWS partition is known" + }, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": { + "userValue": true, + "recommendedValue": true, + "explanation": "Event Rules may only push to encrypted SQS queues in the same account" + }, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": { + "userValue": true, + "recommendedValue": true, + "explanation": "Avoid setting the \"ECS\" deployment controller when adding a circuit breaker" + }, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature to create default policy names for imported roles that depend on the stack the role is in." + }, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use S3 Bucket Policy instead of ACLs for Server Access Logging" + }, + "@aws-cdk/aws-route53-patters:useCertificate": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use the official `Certificate` resource instead of `DnsValidatedCertificate`" + }, + "@aws-cdk/customresources:installLatestAwsSdkDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "Whether to install the latest SDK by default in AwsCustomResource" + }, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use unique resource name for Database Proxy" + }, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Remove CloudWatch alarms from deployment group" + }, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include authorizer configuration in the calculation of the API deployment logical ID." + }, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": { + "userValue": true, + "recommendedValue": true, + "explanation": "Define user data for a launch template by default when a machine image is provided." + }, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": { + "userValue": true, + "recommendedValue": true, + "explanation": "SecretTargetAttachments uses the ResourcePolicy of the attached Secret." + }, + "@aws-cdk/aws-redshift:columnId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Whether to use an ID to track Redshift column changes" + }, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable AmazonEMRServicePolicy_v2 managed policies" + }, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict access to the VPC default security group" + }, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a unique id for each RequestValidator added to a method" + }, + "@aws-cdk/aws-kms:aliasNameRef": { + "userValue": true, + "recommendedValue": true, + "explanation": "KMS Alias name and keyArn will have implicit reference to KMS Key" + }, + "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition" + }, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a launch template when creating an AutoScalingGroup" + }, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include the stack prefix in the stack name generation process" + }, + "@aws-cdk/aws-efs:denyAnonymousAccess": { + "userValue": true, + "recommendedValue": true, + "explanation": "EFS denies anonymous clients accesses" + }, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables support for Multi-AZ with Standby deployment for opensearch domains" + }, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables aws-lambda-nodejs.Function to use the latest available NodeJs runtime as the default" + }, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, mount targets will have a stable logicalId that is linked to the associated subnet." + }, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change." + }, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id." + }, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials." + }, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the CodeCommit source action is using the default branch name 'main'." + }, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default value for crossAccountKeys to false." + }, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default pipeline type to V2." + }, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only." + }, + "@aws-cdk/pipelines:reduceAssetRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from PipelineAssetsFileRole trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-eks:nodegroupNameAttribute": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, nodegroupName attribute of the provisioned EKS NodeGroup will not have the cluster name prefix." + }, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default volume type of the EBS volume will be GP3" + }, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, remove default deployment alarm settings" + }, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default" + }, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack." + }, + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": { + "recommendedValue": true, + "explanation": "When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:explicitStackTags": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, stack tags need to be assigned explicitly on a Stack." + }, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": { + "userValue": false, + "recommendedValue": false, + "explanation": "When set to true along with canContainersAccessInstanceRole=false in ECS cluster, new updated commands will be added to UserData to block container accessing IMDS. **Applicable to Linux only. IMPORTANT: See [details.](#aws-cdkaws-ecsenableImdsBlockingDeprecatedFeature)**" + }, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, CDK synth will throw exception if canContainersAccessInstanceRole is false. **IMPORTANT: See [details.](#aws-cdkaws-ecsdisableEcsImdsBlocking)**" + }, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, we will only grant the necessary permissions when users specify cloudwatch log group through logConfiguration" + }, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas" + }, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together." + }, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn." + }, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`" + }, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values." + }, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, both `@aws-sdk` and `@smithy` packages will be excluded from the Lambda Node.js 18.x runtime to prevent version mismatches in bundled applications." + }, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN." + }, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2." + }, + "@aws-cdk/core:aspectStabilization": { + "recommendedValue": true, + "explanation": "When enabled, a stabilization loop will be run when invoking Aspects during synthesis.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, use a new method for DNS Name of user pool domain target without creating a custom resource." + }, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default security group ingress rules will allow IPv6 ingress from anywhere" + }, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default behaviour of OIDC provider will reject unauthorized connections" + }, + "@aws-cdk/core:enableAdditionalMetadataCollection": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues." + }, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": { + "userValue": false, + "recommendedValue": false, + "explanation": "[Deprecated] When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement" + }, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will automatically generate a unique role name that is used for s3 object replication." + }, + "@aws-cdk/pipelines:reduceStageRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from Stage addActions trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-events:requireEventBusPolicySid": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, grantPutEventsTo() will use resource policies with Statement IDs for service principals." + }, + "@aws-cdk/core:aspectPrioritiesMutating": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, Aspects added by the construct library on your behalf will be given a priority of MUTATING." + }, + "@aws-cdk/aws-dynamodb:retainTableReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, table replica will be default to the removal policy of source table unless specified otherwise." + }, + "@aws-cdk/cognito:logUserPoolClientSecretValue": { + "recommendedValue": false, + "explanation": "When disabled, the value of the user pool client secret will not be logged in the custom resource lambda function logs." + }, + "@aws-cdk/pipelines:reduceCrossAccountActionRoleTrustScope": { + "recommendedValue": true, + "explanation": "When enabled, scopes down the trust policy for the cross-account action role", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resultWriterV2 property of DistributedMap will be used insted of resultWriter" + }, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": { + "userValue": true, + "recommendedValue": true, + "explanation": "Add an S3 trust policy to a KMS key resource policy for SNS subscriptions." + }, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the EgressOnlyGateway resource is only created if private subnets are defined in the dual-stack VPC." + }, + "@aws-cdk/aws-ec2-alpha:useResourceIdForVpcV2Migration": { + "recommendedValue": false, + "explanation": "When enabled, use resource IDs for VPC V2 migration" + }, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined." + }, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK creates and manages loggroup for the lambda function" + }, + "@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault": { + "recommendedValue": true, + "explanation": "When enabled, Network Load Balancer will be created with a security group by default." + }, + "@aws-cdk/aws-stepfunctions-tasks:httpInvokeDynamicJsonPathEndpoint": { + "recommendedValue": true, + "explanation": "When enabled, allows using a dynamic apiEndpoint with JSONPath format in HttpInvoke tasks.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": { + "recommendedValue": true, + "explanation": "When enabled, ECS patterns will generate unique target group IDs to prevent conflicts during load balancer replacement" + } + } + } + } + }, + "minimumCliVersion": "2.1031.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/tree.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/tree.json new file mode 100644 index 0000000000000..c57615ea26cc9 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-imagebuilder-component-all-parameters":{"id":"aws-cdk-imagebuilder-component-all-parameters","path":"aws-cdk-imagebuilder-component-all-parameters","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"Component-EncryptionKey":{"id":"Component-EncryptionKey","path":"aws-cdk-imagebuilder-component-all-parameters/Component-EncryptionKey","constructInfo":{"fqn":"aws-cdk-lib.aws_kms.Key","version":"0.0.0","metadata":[{"removalPolicy":"destroy","pendingWindow":"*"}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-imagebuilder-component-all-parameters/Component-EncryptionKey/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_kms.CfnKey","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::KMS::Key","aws:cdk:cloudformation:props":{"keyPolicy":{"Statement":[{"Action":"kms:*","Effect":"Allow","Principal":{"AWS":{"Fn::Join":["",["arn:",{"Ref":"AWS::Partition"},":iam::",{"Ref":"AWS::AccountId"},":root"]]}},"Resource":"*"}],"Version":"2012-10-17"},"pendingWindowInDays":7}}}}},"InlineComponent":{"id":"InlineComponent","path":"aws-cdk-imagebuilder-component-all-parameters/InlineComponent","constructInfo":{"fqn":"@aws-cdk/aws-imagebuilder-alpha.Component","version":"0.0.0","metadata":[]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-imagebuilder-component-all-parameters/InlineComponent/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_imagebuilder.CfnComponent","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::ImageBuilder::Component","aws:cdk:cloudformation:props":{"changeDescription":"This is a change description","data":"name: test-component\nschemaVersion: \"1.0\"\nconstants:\n - constant:\n type: string\n value: constant value\nparameters:\n - parameter:\n type: string\n description: This is a parameter\n default: default value\nphases:\n - name: build\n steps:\n - name: hello-world-build\n action: ExecuteBash\n onFailure: Continue\n timeoutSeconds: 720\n inputs:\n commands:\n - echo \"Hello build! {{ parameter }} {{ constant }}\"\n - name: validate\n steps:\n - name: hello-world-validate\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello validate!\"\n - name: test\n steps:\n - name: hello-world-test\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello test!\"\n","description":"This is a test component","kmsKeyId":{"Fn::GetAtt":["ComponentEncryptionKeyAF9A6C9C","Arn"]},"name":"aws-cdk-imagebuilder-component-all-parameters-inline","platform":"Linux","supportedOsVersions":["Amazon Linux","Custom OS"],"version":"1.0.0"}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-imagebuilder-component-all-parameters/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-imagebuilder-component-all-parameters/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"ComponentTest":{"id":"ComponentTest","path":"ComponentTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"ComponentTest/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"ComponentTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"ComponentTest/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.ts new file mode 100644 index 0000000000000..376b5d933bcb6 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.all-parameters.component.ts @@ -0,0 +1,81 @@ +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as kms from 'aws-cdk-lib/aws-kms'; +import * as imagebuilder from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-imagebuilder-component-all-parameters'); + +const key = new kms.Key(stack, 'Component-EncryptionKey', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + pendingWindow: cdk.Duration.days(7), +}); + +new imagebuilder.Component(stack, 'InlineComponent', { + componentName: 'aws-cdk-imagebuilder-component-all-parameters-inline', + componentVersion: '1.0.0', + description: 'This is a test component', + changeDescription: 'This is a change description', + platform: imagebuilder.Platform.LINUX, + kmsKey: key, + supportedOsVersions: [ + imagebuilder.OSVersion.AMAZON_LINUX, + imagebuilder.OSVersion.custom(imagebuilder.Platform.LINUX, 'Custom OS'), + ], + data: imagebuilder.ComponentData.fromComponentDocumentJsonObject({ + name: 'test-component', + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + parameters: { + parameter: { + type: imagebuilder.ComponentParameterType.STRING, + description: 'This is a parameter', + default: 'default value', + }, + }, + constants: { constant: imagebuilder.ComponentConstantValue.fromString('constant value') }, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'hello-world-build', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + onFailure: imagebuilder.ComponentOnFailure.CONTINUE, + timeout: cdk.Duration.seconds(720), + inputs: imagebuilder.ComponentStepInputs.fromObject({ + commands: ['echo "Hello build! {{ parameter }} {{ constant }}"'], + }), + }, + ], + }, + { + name: imagebuilder.ComponentPhaseName.VALIDATE, + steps: [ + { + name: 'hello-world-validate', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + inputs: imagebuilder.ComponentStepInputs.fromObject({ + commands: ['echo "Hello validate!"'], + }), + }, + ], + }, + { + name: imagebuilder.ComponentPhaseName.TEST, + steps: [ + { + name: 'hello-world-test', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + inputs: imagebuilder.ComponentStepInputs.fromObject({ + commands: ['echo "Hello test!"'], + }), + }, + ], + }, + ], + }), +}); + +new integ.IntegTest(app, 'ComponentTest', { + testCases: [stack], +}); diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json new file mode 100644 index 0000000000000..ee59271eedeee --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "ComponentTestDefaultTestDeployAssert990A2773 Template", + "source": { + "path": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-d8d86b35": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml new file mode 100644 index 0000000000000..5dde0514b5313 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml @@ -0,0 +1,28 @@ +name: HelloWorldBuildDocument +description: This is hello world build document. +schemaVersion: 1.0 + +phases: + - name: build + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Build." + + - name: validate + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Validate." + + - name: test + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Test." diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.assets.json new file mode 100644 index 0000000000000..4ec08edde7f21 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.assets.json @@ -0,0 +1,34 @@ +{ + "version": "48.0.0", + "files": { + "bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52": { + "displayName": "ComponentData", + "source": { + "path": "asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-35ae9dba": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "6702615e354c0250d99a10a0811e7a66f4905a1af67532bd7377e59c8dbbd8a3": { + "displayName": "aws-cdk-imagebuilder-component-asset Template", + "source": { + "path": "aws-cdk-imagebuilder-component-asset.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-9618aaf3": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6702615e354c0250d99a10a0811e7a66f4905a1af67532bd7377e59c8dbbd8a3.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.template.json new file mode 100644 index 0000000000000..1286e695af80e --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/aws-cdk-imagebuilder-component-asset.template.json @@ -0,0 +1,58 @@ +{ + "Resources": { + "S3AssetComponentBDFBFAD2": { + "Type": "AWS::ImageBuilder::Component", + "Properties": { + "Name": "aws-cdk-imagebuilder-component-all-parameters-s3-asset-component", + "Platform": "Linux", + "Uri": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml" + ] + ] + }, + "Version": "1.0.0" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/cdk.out b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/cdk.out new file mode 100644 index 0000000000000..523a9aac37cbf --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"48.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/integ.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/integ.json new file mode 100644 index 0000000000000..887850db8e480 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "48.0.0", + "testCases": { + "ComponentTest/DefaultTest": { + "stacks": [ + "aws-cdk-imagebuilder-component-asset" + ], + "assertionStack": "ComponentTest/DefaultTest/DeployAssert", + "assertionStackName": "ComponentTestDefaultTestDeployAssert990A2773" + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/manifest.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/manifest.json new file mode 100644 index 0000000000000..d8b698becc874 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/manifest.json @@ -0,0 +1,603 @@ +{ + "version": "48.0.0", + "artifacts": { + "aws-cdk-imagebuilder-component-asset.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-imagebuilder-component-asset.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-imagebuilder-component-asset": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-imagebuilder-component-asset.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6702615e354c0250d99a10a0811e7a66f4905a1af67532bd7377e59c8dbbd8a3.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-imagebuilder-component-asset.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-imagebuilder-component-asset.assets" + ], + "metadata": { + "/aws-cdk-imagebuilder-component-asset/S3AssetComponent/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "S3AssetComponentBDFBFAD2" + } + ], + "/aws-cdk-imagebuilder-component-asset/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-imagebuilder-component-asset/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-imagebuilder-component-asset" + }, + "ComponentTestDefaultTestDeployAssert990A2773.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ComponentTestDefaultTestDeployAssert990A2773.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ComponentTestDefaultTestDeployAssert990A2773": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "metadata": { + "/ComponentTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ComponentTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "aws-cdk-lib/feature-flag-report": { + "type": "cdk:feature-flag-report", + "properties": { + "module": "aws-cdk-lib", + "flags": { + "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": { + "recommendedValue": true, + "explanation": "Pass signingProfileName to CfnSigningProfile" + }, + "@aws-cdk/core:newStyleStackSynthesis": { + "recommendedValue": true, + "explanation": "Switch to new stack synthesis method which enables CI/CD", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:stackRelativeExports": { + "recommendedValue": true, + "explanation": "Name exports based on the construct paths relative to the stack, rather than the global construct path", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": { + "recommendedValue": true, + "explanation": "Disable implicit openListener when custom security groups are provided" + }, + "@aws-cdk/aws-rds:lowercaseDbIdentifier": { + "recommendedValue": true, + "explanation": "Force lowercasing of RDS Cluster names in CDK", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": { + "recommendedValue": true, + "explanation": "Allow adding/removing multiple UsagePlanKeys independently", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeVersionProps": { + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeLayerVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`." + }, + "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": { + "recommendedValue": true, + "explanation": "Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:checkSecretUsage": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this flag to make it impossible to accidentally use SecretValues in unsafe locations" + }, + "@aws-cdk/core:target-partitions": { + "recommendedValue": [ + "aws", + "aws-cn" + ], + "explanation": "What regions to include in lookup tables of environment agnostic stacks" + }, + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": { + "userValue": true, + "recommendedValue": true, + "explanation": "ECS extensions will automatically add an `awslogs` driver if no logging is specified" + }, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to have Launch Templates generated by the `InstanceRequireImdsv2Aspect` use unique names." + }, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": { + "userValue": true, + "recommendedValue": true, + "explanation": "ARN format used by ECS. In the new ARN format, the cluster name is part of the resource ID." + }, + "@aws-cdk/aws-iam:minimizePolicies": { + "userValue": true, + "recommendedValue": true, + "explanation": "Minimize IAM policies by combining Statements" + }, + "@aws-cdk/core:validateSnapshotRemovalPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Error on snapshot removal policies on resources that do not support it." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate key aliases that include the stack name" + }, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to create an S3 bucket policy by default in cases where an AWS service would automatically create the Policy if one does not exist." + }, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict KMS key policy for encrypted Queues a bit more" + }, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make default CloudWatch Role behavior safe for multiple API Gateways in one environment" + }, + "@aws-cdk/core:enablePartitionLiterals": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make ARNs concrete if AWS partition is known" + }, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": { + "userValue": true, + "recommendedValue": true, + "explanation": "Event Rules may only push to encrypted SQS queues in the same account" + }, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": { + "userValue": true, + "recommendedValue": true, + "explanation": "Avoid setting the \"ECS\" deployment controller when adding a circuit breaker" + }, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature to by default create default policy names for imported roles that depend on the stack the role is in." + }, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use S3 Bucket Policy instead of ACLs for Server Access Logging" + }, + "@aws-cdk/aws-route53-patters:useCertificate": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use the official `Certificate` resource instead of `DnsValidatedCertificate`" + }, + "@aws-cdk/customresources:installLatestAwsSdkDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "Whether to install the latest SDK by default in AwsCustomResource" + }, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use unique resource name for Database Proxy" + }, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Remove CloudWatch alarms from deployment group" + }, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include authorizer configuration in the calculation of the API deployment logical ID." + }, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": { + "userValue": true, + "recommendedValue": true, + "explanation": "Define user data for a launch template by default when a machine image is provided." + }, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": { + "userValue": true, + "recommendedValue": true, + "explanation": "SecretTargetAttachments uses the ResourcePolicy of the attached Secret." + }, + "@aws-cdk/aws-redshift:columnId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Whether to use an ID to track Redshift column changes" + }, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable AmazonEMRServicePolicy_v2 managed policies" + }, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict access to the VPC default security group" + }, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a unique id for each RequestValidator added to a method" + }, + "@aws-cdk/aws-kms:aliasNameRef": { + "userValue": true, + "recommendedValue": true, + "explanation": "KMS Alias name and keyArn will have implicit reference to KMS Key" + }, + "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition" + }, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a launch template when creating an AutoScalingGroup" + }, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include the stack prefix in the stack name generation process" + }, + "@aws-cdk/aws-efs:denyAnonymousAccess": { + "userValue": true, + "recommendedValue": true, + "explanation": "EFS denies anonymous clients accesses" + }, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables support for Multi-AZ with Standby deployment for opensearch domains" + }, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables aws-lambda-nodejs.Function to use the latest available NodeJs runtime as the default" + }, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, mount targets will have a stable logicalId that is linked to the associated subnet." + }, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change." + }, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id." + }, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials." + }, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the CodeCommit source action is using the default branch name 'main'." + }, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default value for crossAccountKeys to false." + }, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default pipeline type to V2." + }, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only." + }, + "@aws-cdk/pipelines:reduceAssetRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from PipelineAssetsFileRole trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-eks:nodegroupNameAttribute": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, nodegroupName attribute of the provisioned EKS NodeGroup will not have the cluster name prefix." + }, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default volume type of the EBS volume will be GP3" + }, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, remove default deployment alarm settings" + }, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default" + }, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack." + }, + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": { + "recommendedValue": true, + "explanation": "When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:explicitStackTags": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, stack tags need to be assigned explicitly on a Stack." + }, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": { + "userValue": false, + "recommendedValue": false, + "explanation": "When set to true along with canContainersAccessInstanceRole=false in ECS cluster, new updated commands will be added to UserData to block container accessing IMDS. **Applicable to Linux only. IMPORTANT: See [details.](#aws-cdkaws-ecsenableImdsBlockingDeprecatedFeature)**" + }, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, CDK synth will throw exception if canContainersAccessInstanceRole is false. **IMPORTANT: See [details.](#aws-cdkaws-ecsdisableEcsImdsBlocking)**" + }, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, we will only grant the necessary permissions when users specify cloudwatch log group through logConfiguration" + }, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas" + }, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together." + }, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn." + }, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`" + }, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values." + }, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, both `@aws-sdk` and `@smithy` packages will be excluded from the Lambda Node.js 18.x runtime to prevent version mismatches in bundled applications." + }, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN." + }, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2." + }, + "@aws-cdk/core:aspectStabilization": { + "recommendedValue": true, + "explanation": "When enabled, a stabilization loop will be run when invoking Aspects during synthesis.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, use a new method for DNS Name of user pool domain target without creating a custom resource." + }, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default security group ingress rules will allow IPv6 ingress from anywhere" + }, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default behaviour of OIDC provider will reject unauthorized connections" + }, + "@aws-cdk/core:enableAdditionalMetadataCollection": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues." + }, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": { + "userValue": false, + "recommendedValue": false, + "explanation": "[Deprecated] When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement" + }, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will automatically generate a unique role name that is used for s3 object replication." + }, + "@aws-cdk/pipelines:reduceStageRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from Stage addActions trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-events:requireEventBusPolicySid": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, grantPutEventsTo() will use resource policies with Statement IDs for service principals." + }, + "@aws-cdk/core:aspectPrioritiesMutating": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, Aspects added by the construct library on your behalf will be given a priority of MUTATING." + }, + "@aws-cdk/aws-dynamodb:retainTableReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, table replica will be default to the removal policy of source table unless specified otherwise." + }, + "@aws-cdk/cognito:logUserPoolClientSecretValue": { + "recommendedValue": false, + "explanation": "When disabled, the value of the user pool client secret will not be logged in the custom resource lambda function logs." + }, + "@aws-cdk/pipelines:reduceCrossAccountActionRoleTrustScope": { + "recommendedValue": true, + "explanation": "When enabled, scopes down the trust policy for the cross-account action role", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resultWriterV2 property of DistributedMap will be used insted of resultWriter" + }, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": { + "userValue": true, + "recommendedValue": true, + "explanation": "Add an S3 trust policy to a KMS key resource policy for SNS subscriptions." + }, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the EgressOnlyGateway resource is only created if private subnets are defined in the dual-stack VPC." + }, + "@aws-cdk/aws-ec2-alpha:useResourceIdForVpcV2Migration": { + "recommendedValue": false, + "explanation": "When enabled, use resource IDs for VPC V2 migration" + }, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined." + }, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK creates and manages loggroup for the lambda function" + }, + "@aws-cdk/aws-stepfunctions-tasks:httpInvokeDynamicJsonPathEndpoint": { + "recommendedValue": true, + "explanation": "When enabled, allows using a dynamic apiEndpoint with JSONPath format in HttpInvoke tasks.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": { + "recommendedValue": true, + "explanation": "When enabled, ECS patterns will generate unique target group IDs to prevent conflicts during load balancer replacement" + } + } + } + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/tree.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/tree.json new file mode 100644 index 0000000000000..ce57d67e2d617 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-imagebuilder-component-asset":{"id":"aws-cdk-imagebuilder-component-asset","path":"aws-cdk-imagebuilder-component-asset","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"ComponentData":{"id":"ComponentData","path":"aws-cdk-imagebuilder-component-asset/ComponentData","constructInfo":{"fqn":"aws-cdk-lib.aws_s3_assets.Asset","version":"0.0.0"},"children":{"Stage":{"id":"Stage","path":"aws-cdk-imagebuilder-component-asset/ComponentData/Stage","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"AssetBucket":{"id":"AssetBucket","path":"aws-cdk-imagebuilder-component-asset/ComponentData/AssetBucket","constructInfo":{"fqn":"aws-cdk-lib.aws_s3.BucketBase","version":"0.0.0","metadata":[]}}}},"S3AssetComponent":{"id":"S3AssetComponent","path":"aws-cdk-imagebuilder-component-asset/S3AssetComponent","constructInfo":{"fqn":"@aws-cdk/aws-imagebuilder-alpha.Component","version":"0.0.0","metadata":[]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-imagebuilder-component-asset/S3AssetComponent/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_imagebuilder.CfnComponent","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::ImageBuilder::Component","aws:cdk:cloudformation:props":{"name":"aws-cdk-imagebuilder-component-all-parameters-s3-asset-component","platform":"Linux","uri":{"Fn::Join":["",["s3://",{"Fn::Sub":"cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"},"/bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml"]]},"version":"1.0.0"}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-imagebuilder-component-asset/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-imagebuilder-component-asset/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"ComponentTest":{"id":"ComponentTest","path":"ComponentTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"ComponentTest/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"ComponentTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"ComponentTest/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.ts new file mode 100644 index 0000000000000..eab1d64479999 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.asset.component.ts @@ -0,0 +1,22 @@ +import * as path from 'path'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as imagebuilder from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-imagebuilder-component-asset'); + +new imagebuilder.Component(stack, 'S3AssetComponent', { + componentName: 'aws-cdk-imagebuilder-component-all-parameters-s3-asset-component', + componentVersion: '1.0.0', + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromAsset( + stack, + 'ComponentData', + path.join(__dirname, 'assets', 'component-data.yaml'), + ), +}); + +new integ.IntegTest(app, 'ComponentTest', { + testCases: [stack], +}); diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets.json new file mode 100644 index 0000000000000..c8da5f4c9085f --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732 Template", + "source": { + "path": "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-d8d86b35": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.assets.json new file mode 100644 index 0000000000000..062ef8750cf17 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "dfdd5642c47c69f058482d81c615da4228623f8b7a38485f735d095c5629b3a9": { + "displayName": "aws-cdk-imagebuilder-component-default-parameters Template", + "source": { + "path": "aws-cdk-imagebuilder-component-default-parameters.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-24ad0c8b": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "dfdd5642c47c69f058482d81c615da4228623f8b7a38485f735d095c5629b3a9.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.template.json new file mode 100644 index 0000000000000..a92ead5227575 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/aws-cdk-imagebuilder-component-default-parameters.template.json @@ -0,0 +1,47 @@ +{ + "Resources": { + "Component0EED0119": { + "Type": "AWS::ImageBuilder::Component", + "Properties": { + "Data": "name: test-component\nschemaVersion: \"1.0\"\nphases:\n - name: build\n steps:\n - name: hello-world-build\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello build!\"\n", + "Name": "aws-cdk-imagebuilder-component-default-parameters-component-08a15319", + "Platform": "Linux", + "Version": "1.0.0" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/cdk.out b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/cdk.out new file mode 100644 index 0000000000000..523a9aac37cbf --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"48.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/integ.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/integ.json new file mode 100644 index 0000000000000..aa2061c9a2bf4 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "48.0.0", + "testCases": { + "InfrastructureConfigurationTest/DefaultTest": { + "stacks": [ + "aws-cdk-imagebuilder-component-default-parameters" + ], + "assertionStack": "InfrastructureConfigurationTest/DefaultTest/DeployAssert", + "assertionStackName": "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732" + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/manifest.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/manifest.json new file mode 100644 index 0000000000000..5c4675da2fd5f --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/manifest.json @@ -0,0 +1,603 @@ +{ + "version": "48.0.0", + "artifacts": { + "aws-cdk-imagebuilder-component-default-parameters.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-imagebuilder-component-default-parameters.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-imagebuilder-component-default-parameters": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-imagebuilder-component-default-parameters.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dfdd5642c47c69f058482d81c615da4228623f8b7a38485f735d095c5629b3a9.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-imagebuilder-component-default-parameters.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-imagebuilder-component-default-parameters.assets" + ], + "metadata": { + "/aws-cdk-imagebuilder-component-default-parameters/Component/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Component0EED0119" + } + ], + "/aws-cdk-imagebuilder-component-default-parameters/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-imagebuilder-component-default-parameters/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-imagebuilder-component-default-parameters" + }, + "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "InfrastructureConfigurationTestDefaultTestDeployAssert6566C732.assets" + ], + "metadata": { + "/InfrastructureConfigurationTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/InfrastructureConfigurationTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "InfrastructureConfigurationTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "aws-cdk-lib/feature-flag-report": { + "type": "cdk:feature-flag-report", + "properties": { + "module": "aws-cdk-lib", + "flags": { + "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": { + "recommendedValue": true, + "explanation": "Pass signingProfileName to CfnSigningProfile" + }, + "@aws-cdk/core:newStyleStackSynthesis": { + "recommendedValue": true, + "explanation": "Switch to new stack synthesis method which enables CI/CD", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:stackRelativeExports": { + "recommendedValue": true, + "explanation": "Name exports based on the construct paths relative to the stack, rather than the global construct path", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": { + "recommendedValue": true, + "explanation": "Disable implicit openListener when custom security groups are provided" + }, + "@aws-cdk/aws-rds:lowercaseDbIdentifier": { + "recommendedValue": true, + "explanation": "Force lowercasing of RDS Cluster names in CDK", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": { + "recommendedValue": true, + "explanation": "Allow adding/removing multiple UsagePlanKeys independently", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeVersionProps": { + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeLayerVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`." + }, + "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": { + "recommendedValue": true, + "explanation": "Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:checkSecretUsage": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this flag to make it impossible to accidentally use SecretValues in unsafe locations" + }, + "@aws-cdk/core:target-partitions": { + "recommendedValue": [ + "aws", + "aws-cn" + ], + "explanation": "What regions to include in lookup tables of environment agnostic stacks" + }, + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": { + "userValue": true, + "recommendedValue": true, + "explanation": "ECS extensions will automatically add an `awslogs` driver if no logging is specified" + }, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to have Launch Templates generated by the `InstanceRequireImdsv2Aspect` use unique names." + }, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": { + "userValue": true, + "recommendedValue": true, + "explanation": "ARN format used by ECS. In the new ARN format, the cluster name is part of the resource ID." + }, + "@aws-cdk/aws-iam:minimizePolicies": { + "userValue": true, + "recommendedValue": true, + "explanation": "Minimize IAM policies by combining Statements" + }, + "@aws-cdk/core:validateSnapshotRemovalPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Error on snapshot removal policies on resources that do not support it." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate key aliases that include the stack name" + }, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to create an S3 bucket policy by default in cases where an AWS service would automatically create the Policy if one does not exist." + }, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict KMS key policy for encrypted Queues a bit more" + }, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make default CloudWatch Role behavior safe for multiple API Gateways in one environment" + }, + "@aws-cdk/core:enablePartitionLiterals": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make ARNs concrete if AWS partition is known" + }, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": { + "userValue": true, + "recommendedValue": true, + "explanation": "Event Rules may only push to encrypted SQS queues in the same account" + }, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": { + "userValue": true, + "recommendedValue": true, + "explanation": "Avoid setting the \"ECS\" deployment controller when adding a circuit breaker" + }, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature to by default create default policy names for imported roles that depend on the stack the role is in." + }, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use S3 Bucket Policy instead of ACLs for Server Access Logging" + }, + "@aws-cdk/aws-route53-patters:useCertificate": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use the official `Certificate` resource instead of `DnsValidatedCertificate`" + }, + "@aws-cdk/customresources:installLatestAwsSdkDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "Whether to install the latest SDK by default in AwsCustomResource" + }, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use unique resource name for Database Proxy" + }, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Remove CloudWatch alarms from deployment group" + }, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include authorizer configuration in the calculation of the API deployment logical ID." + }, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": { + "userValue": true, + "recommendedValue": true, + "explanation": "Define user data for a launch template by default when a machine image is provided." + }, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": { + "userValue": true, + "recommendedValue": true, + "explanation": "SecretTargetAttachments uses the ResourcePolicy of the attached Secret." + }, + "@aws-cdk/aws-redshift:columnId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Whether to use an ID to track Redshift column changes" + }, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable AmazonEMRServicePolicy_v2 managed policies" + }, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict access to the VPC default security group" + }, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a unique id for each RequestValidator added to a method" + }, + "@aws-cdk/aws-kms:aliasNameRef": { + "userValue": true, + "recommendedValue": true, + "explanation": "KMS Alias name and keyArn will have implicit reference to KMS Key" + }, + "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition" + }, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a launch template when creating an AutoScalingGroup" + }, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include the stack prefix in the stack name generation process" + }, + "@aws-cdk/aws-efs:denyAnonymousAccess": { + "userValue": true, + "recommendedValue": true, + "explanation": "EFS denies anonymous clients accesses" + }, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables support for Multi-AZ with Standby deployment for opensearch domains" + }, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables aws-lambda-nodejs.Function to use the latest available NodeJs runtime as the default" + }, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, mount targets will have a stable logicalId that is linked to the associated subnet." + }, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change." + }, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id." + }, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials." + }, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the CodeCommit source action is using the default branch name 'main'." + }, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default value for crossAccountKeys to false." + }, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default pipeline type to V2." + }, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only." + }, + "@aws-cdk/pipelines:reduceAssetRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from PipelineAssetsFileRole trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-eks:nodegroupNameAttribute": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, nodegroupName attribute of the provisioned EKS NodeGroup will not have the cluster name prefix." + }, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default volume type of the EBS volume will be GP3" + }, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, remove default deployment alarm settings" + }, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default" + }, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack." + }, + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": { + "recommendedValue": true, + "explanation": "When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:explicitStackTags": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, stack tags need to be assigned explicitly on a Stack." + }, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": { + "userValue": false, + "recommendedValue": false, + "explanation": "When set to true along with canContainersAccessInstanceRole=false in ECS cluster, new updated commands will be added to UserData to block container accessing IMDS. **Applicable to Linux only. IMPORTANT: See [details.](#aws-cdkaws-ecsenableImdsBlockingDeprecatedFeature)**" + }, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, CDK synth will throw exception if canContainersAccessInstanceRole is false. **IMPORTANT: See [details.](#aws-cdkaws-ecsdisableEcsImdsBlocking)**" + }, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, we will only grant the necessary permissions when users specify cloudwatch log group through logConfiguration" + }, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas" + }, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together." + }, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn." + }, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`" + }, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values." + }, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, both `@aws-sdk` and `@smithy` packages will be excluded from the Lambda Node.js 18.x runtime to prevent version mismatches in bundled applications." + }, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN." + }, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2." + }, + "@aws-cdk/core:aspectStabilization": { + "recommendedValue": true, + "explanation": "When enabled, a stabilization loop will be run when invoking Aspects during synthesis.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, use a new method for DNS Name of user pool domain target without creating a custom resource." + }, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default security group ingress rules will allow IPv6 ingress from anywhere" + }, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default behaviour of OIDC provider will reject unauthorized connections" + }, + "@aws-cdk/core:enableAdditionalMetadataCollection": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues." + }, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": { + "userValue": false, + "recommendedValue": false, + "explanation": "[Deprecated] When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement" + }, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will automatically generate a unique role name that is used for s3 object replication." + }, + "@aws-cdk/pipelines:reduceStageRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from Stage addActions trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-events:requireEventBusPolicySid": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, grantPutEventsTo() will use resource policies with Statement IDs for service principals." + }, + "@aws-cdk/core:aspectPrioritiesMutating": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, Aspects added by the construct library on your behalf will be given a priority of MUTATING." + }, + "@aws-cdk/aws-dynamodb:retainTableReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, table replica will be default to the removal policy of source table unless specified otherwise." + }, + "@aws-cdk/cognito:logUserPoolClientSecretValue": { + "recommendedValue": false, + "explanation": "When disabled, the value of the user pool client secret will not be logged in the custom resource lambda function logs." + }, + "@aws-cdk/pipelines:reduceCrossAccountActionRoleTrustScope": { + "recommendedValue": true, + "explanation": "When enabled, scopes down the trust policy for the cross-account action role", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resultWriterV2 property of DistributedMap will be used insted of resultWriter" + }, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": { + "userValue": true, + "recommendedValue": true, + "explanation": "Add an S3 trust policy to a KMS key resource policy for SNS subscriptions." + }, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the EgressOnlyGateway resource is only created if private subnets are defined in the dual-stack VPC." + }, + "@aws-cdk/aws-ec2-alpha:useResourceIdForVpcV2Migration": { + "recommendedValue": false, + "explanation": "When enabled, use resource IDs for VPC V2 migration" + }, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined." + }, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK creates and manages loggroup for the lambda function" + }, + "@aws-cdk/aws-stepfunctions-tasks:httpInvokeDynamicJsonPathEndpoint": { + "recommendedValue": true, + "explanation": "When enabled, allows using a dynamic apiEndpoint with JSONPath format in HttpInvoke tasks.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": { + "recommendedValue": true, + "explanation": "When enabled, ECS patterns will generate unique target group IDs to prevent conflicts during load balancer replacement" + } + } + } + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/tree.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/tree.json new file mode 100644 index 0000000000000..1a7c21b9e5e3e --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-imagebuilder-component-default-parameters":{"id":"aws-cdk-imagebuilder-component-default-parameters","path":"aws-cdk-imagebuilder-component-default-parameters","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"Component":{"id":"Component","path":"aws-cdk-imagebuilder-component-default-parameters/Component","constructInfo":{"fqn":"@aws-cdk/aws-imagebuilder-alpha.Component","version":"0.0.0","metadata":[]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-imagebuilder-component-default-parameters/Component/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_imagebuilder.CfnComponent","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::ImageBuilder::Component","aws:cdk:cloudformation:props":{"data":"name: test-component\nschemaVersion: \"1.0\"\nphases:\n - name: build\n steps:\n - name: hello-world-build\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello build!\"\n","name":"aws-cdk-imagebuilder-component-default-parameters-component-08a15319","platform":"Linux","version":"1.0.0"}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-imagebuilder-component-default-parameters/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-imagebuilder-component-default-parameters/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"InfrastructureConfigurationTest":{"id":"InfrastructureConfigurationTest","path":"InfrastructureConfigurationTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"InfrastructureConfigurationTest/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"InfrastructureConfigurationTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"InfrastructureConfigurationTest/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"InfrastructureConfigurationTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"InfrastructureConfigurationTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.ts new file mode 100644 index 0000000000000..c944154c14be0 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.default-parameters.component.ts @@ -0,0 +1,32 @@ +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as imagebuilder from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-imagebuilder-component-default-parameters'); + +new imagebuilder.Component(stack, 'Component', { + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromJsonObject({ + name: 'test-component', + schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, + phases: [ + { + name: imagebuilder.ComponentPhaseName.BUILD, + steps: [ + { + name: 'hello-world-build', + action: imagebuilder.ComponentAction.EXECUTE_BASH, + inputs: { + commands: ['echo "Hello build!"'], + }, + }, + ], + }, + ], + }), +}); + +new integ.IntegTest(app, 'ComponentTest-DefaultParameters', { + testCases: [stack], +}); diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json new file mode 100644 index 0000000000000..ee59271eedeee --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.assets.json @@ -0,0 +1,20 @@ +{ + "version": "48.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "ComponentTestDefaultTestDeployAssert990A2773 Template", + "source": { + "path": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-d8d86b35": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/ComponentTestDefaultTestDeployAssert990A2773.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml new file mode 100644 index 0000000000000..5dde0514b5313 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml @@ -0,0 +1,28 @@ +name: HelloWorldBuildDocument +description: This is hello world build document. +schemaVersion: 1.0 + +phases: + - name: build + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Build." + + - name: validate + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Validate." + + - name: test + steps: + - name: HelloWorldStep + action: ExecuteBash + inputs: + commands: + - echo "Hello World! Test." diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.assets.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.assets.json new file mode 100644 index 0000000000000..c30596845a41a --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.assets.json @@ -0,0 +1,34 @@ +{ + "version": "48.0.0", + "files": { + "bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52": { + "displayName": "asset", + "source": { + "path": "asset.bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-35ae9dba": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "725373b477b838f8002ee36492bc2ad7d45deedd7dd4b8f86c095d38c46a179a": { + "displayName": "aws-cdk-imagebuilder-component-s3-data Template", + "source": { + "path": "aws-cdk-imagebuilder-component-s3-data.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region-f29274d5": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "725373b477b838f8002ee36492bc2ad7d45deedd7dd4b8f86c095d38c46a179a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.template.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.template.json new file mode 100644 index 0000000000000..d4427e2c84db4 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/aws-cdk-imagebuilder-component-s3-data.template.json @@ -0,0 +1,58 @@ +{ + "Resources": { + "S3AssetComponentBDFBFAD2": { + "Type": "AWS::ImageBuilder::Component", + "Properties": { + "Name": "aws-cdk-imagebuilder-component-s3", + "Platform": "Linux", + "Uri": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml" + ] + ] + }, + "Version": "1.0.0" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/cdk.out b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/cdk.out new file mode 100644 index 0000000000000..523a9aac37cbf --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"48.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/integ.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/integ.json new file mode 100644 index 0000000000000..2e623452804d9 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "48.0.0", + "testCases": { + "ComponentTest/DefaultTest": { + "stacks": [ + "aws-cdk-imagebuilder-component-s3-data" + ], + "assertionStack": "ComponentTest/DefaultTest/DeployAssert", + "assertionStackName": "ComponentTestDefaultTestDeployAssert990A2773" + } + }, + "minimumCliVersion": "2.1027.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/manifest.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/manifest.json new file mode 100644 index 0000000000000..5d0bb0ac64c77 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/manifest.json @@ -0,0 +1,609 @@ +{ + "version": "48.0.0", + "artifacts": { + "aws-cdk-imagebuilder-component-s3-data.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-imagebuilder-component-s3-data.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-imagebuilder-component-s3-data": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-imagebuilder-component-s3-data.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/725373b477b838f8002ee36492bc2ad7d45deedd7dd4b8f86c095d38c46a179a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-imagebuilder-component-s3-data.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-imagebuilder-component-s3-data.assets" + ], + "metadata": { + "/aws-cdk-imagebuilder-component-s3-data/S3AssetComponent/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "S3AssetComponentBDFBFAD2" + } + ], + "/aws-cdk-imagebuilder-component-s3-data/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-imagebuilder-component-s3-data/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-imagebuilder-component-s3-data" + }, + "ComponentTestDefaultTestDeployAssert990A2773.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ComponentTestDefaultTestDeployAssert990A2773.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ComponentTestDefaultTestDeployAssert990A2773": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ComponentTestDefaultTestDeployAssert990A2773.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "ComponentTestDefaultTestDeployAssert990A2773.assets" + ], + "metadata": { + "/ComponentTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ComponentTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "aws-cdk-lib/feature-flag-report": { + "type": "cdk:feature-flag-report", + "properties": { + "module": "aws-cdk-lib", + "flags": { + "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": { + "userValue": true, + "recommendedValue": true, + "explanation": "Pass signingProfileName to CfnSigningProfile" + }, + "@aws-cdk/core:newStyleStackSynthesis": { + "recommendedValue": true, + "explanation": "Switch to new stack synthesis method which enables CI/CD", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:stackRelativeExports": { + "recommendedValue": true, + "explanation": "Name exports based on the construct paths relative to the stack, rather than the global construct path", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": { + "userValue": true, + "recommendedValue": true, + "explanation": "Disable implicit openListener when custom security groups are provided" + }, + "@aws-cdk/aws-rds:lowercaseDbIdentifier": { + "recommendedValue": true, + "explanation": "Force lowercasing of RDS Cluster names in CDK", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": { + "recommendedValue": true, + "explanation": "Allow adding/removing multiple UsagePlanKeys independently", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeVersionProps": { + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeLayerVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`." + }, + "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": { + "recommendedValue": true, + "explanation": "Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:checkSecretUsage": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this flag to make it impossible to accidentally use SecretValues in unsafe locations" + }, + "@aws-cdk/core:target-partitions": { + "recommendedValue": [ + "aws", + "aws-cn" + ], + "explanation": "What regions to include in lookup tables of environment agnostic stacks" + }, + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": { + "userValue": true, + "recommendedValue": true, + "explanation": "ECS extensions will automatically add an `awslogs` driver if no logging is specified" + }, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to have Launch Templates generated by the `InstanceRequireImdsv2Aspect` use unique names." + }, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": { + "userValue": true, + "recommendedValue": true, + "explanation": "ARN format used by ECS. In the new ARN format, the cluster name is part of the resource ID." + }, + "@aws-cdk/aws-iam:minimizePolicies": { + "userValue": true, + "recommendedValue": true, + "explanation": "Minimize IAM policies by combining Statements" + }, + "@aws-cdk/core:validateSnapshotRemovalPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Error on snapshot removal policies on resources that do not support it." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate key aliases that include the stack name" + }, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to create an S3 bucket policy by default in cases where an AWS service would automatically create the Policy if one does not exist." + }, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict KMS key policy for encrypted Queues a bit more" + }, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make default CloudWatch Role behavior safe for multiple API Gateways in one environment" + }, + "@aws-cdk/core:enablePartitionLiterals": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make ARNs concrete if AWS partition is known" + }, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": { + "userValue": true, + "recommendedValue": true, + "explanation": "Event Rules may only push to encrypted SQS queues in the same account" + }, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": { + "userValue": true, + "recommendedValue": true, + "explanation": "Avoid setting the \"ECS\" deployment controller when adding a circuit breaker" + }, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature to create default policy names for imported roles that depend on the stack the role is in." + }, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use S3 Bucket Policy instead of ACLs for Server Access Logging" + }, + "@aws-cdk/aws-route53-patters:useCertificate": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use the official `Certificate` resource instead of `DnsValidatedCertificate`" + }, + "@aws-cdk/customresources:installLatestAwsSdkDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "Whether to install the latest SDK by default in AwsCustomResource" + }, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use unique resource name for Database Proxy" + }, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Remove CloudWatch alarms from deployment group" + }, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include authorizer configuration in the calculation of the API deployment logical ID." + }, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": { + "userValue": true, + "recommendedValue": true, + "explanation": "Define user data for a launch template by default when a machine image is provided." + }, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": { + "userValue": true, + "recommendedValue": true, + "explanation": "SecretTargetAttachments uses the ResourcePolicy of the attached Secret." + }, + "@aws-cdk/aws-redshift:columnId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Whether to use an ID to track Redshift column changes" + }, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable AmazonEMRServicePolicy_v2 managed policies" + }, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict access to the VPC default security group" + }, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a unique id for each RequestValidator added to a method" + }, + "@aws-cdk/aws-kms:aliasNameRef": { + "userValue": true, + "recommendedValue": true, + "explanation": "KMS Alias name and keyArn will have implicit reference to KMS Key" + }, + "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition" + }, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a launch template when creating an AutoScalingGroup" + }, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include the stack prefix in the stack name generation process" + }, + "@aws-cdk/aws-efs:denyAnonymousAccess": { + "userValue": true, + "recommendedValue": true, + "explanation": "EFS denies anonymous clients accesses" + }, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables support for Multi-AZ with Standby deployment for opensearch domains" + }, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables aws-lambda-nodejs.Function to use the latest available NodeJs runtime as the default" + }, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, mount targets will have a stable logicalId that is linked to the associated subnet." + }, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change." + }, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id." + }, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials." + }, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the CodeCommit source action is using the default branch name 'main'." + }, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default value for crossAccountKeys to false." + }, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default pipeline type to V2." + }, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only." + }, + "@aws-cdk/pipelines:reduceAssetRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from PipelineAssetsFileRole trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-eks:nodegroupNameAttribute": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, nodegroupName attribute of the provisioned EKS NodeGroup will not have the cluster name prefix." + }, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default volume type of the EBS volume will be GP3" + }, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, remove default deployment alarm settings" + }, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default" + }, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack." + }, + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": { + "recommendedValue": true, + "explanation": "When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:explicitStackTags": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, stack tags need to be assigned explicitly on a Stack." + }, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": { + "userValue": false, + "recommendedValue": false, + "explanation": "When set to true along with canContainersAccessInstanceRole=false in ECS cluster, new updated commands will be added to UserData to block container accessing IMDS. **Applicable to Linux only. IMPORTANT: See [details.](#aws-cdkaws-ecsenableImdsBlockingDeprecatedFeature)**" + }, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, CDK synth will throw exception if canContainersAccessInstanceRole is false. **IMPORTANT: See [details.](#aws-cdkaws-ecsdisableEcsImdsBlocking)**" + }, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, we will only grant the necessary permissions when users specify cloudwatch log group through logConfiguration" + }, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas" + }, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together." + }, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn." + }, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`" + }, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values." + }, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, both `@aws-sdk` and `@smithy` packages will be excluded from the Lambda Node.js 18.x runtime to prevent version mismatches in bundled applications." + }, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN." + }, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2." + }, + "@aws-cdk/core:aspectStabilization": { + "recommendedValue": true, + "explanation": "When enabled, a stabilization loop will be run when invoking Aspects during synthesis.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, use a new method for DNS Name of user pool domain target without creating a custom resource." + }, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default security group ingress rules will allow IPv6 ingress from anywhere" + }, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default behaviour of OIDC provider will reject unauthorized connections" + }, + "@aws-cdk/core:enableAdditionalMetadataCollection": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues." + }, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": { + "userValue": false, + "recommendedValue": false, + "explanation": "[Deprecated] When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement" + }, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will automatically generate a unique role name that is used for s3 object replication." + }, + "@aws-cdk/pipelines:reduceStageRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from Stage addActions trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-events:requireEventBusPolicySid": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, grantPutEventsTo() will use resource policies with Statement IDs for service principals." + }, + "@aws-cdk/core:aspectPrioritiesMutating": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, Aspects added by the construct library on your behalf will be given a priority of MUTATING." + }, + "@aws-cdk/aws-dynamodb:retainTableReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, table replica will be default to the removal policy of source table unless specified otherwise." + }, + "@aws-cdk/cognito:logUserPoolClientSecretValue": { + "recommendedValue": false, + "explanation": "When disabled, the value of the user pool client secret will not be logged in the custom resource lambda function logs." + }, + "@aws-cdk/pipelines:reduceCrossAccountActionRoleTrustScope": { + "recommendedValue": true, + "explanation": "When enabled, scopes down the trust policy for the cross-account action role", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resultWriterV2 property of DistributedMap will be used insted of resultWriter" + }, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": { + "userValue": true, + "recommendedValue": true, + "explanation": "Add an S3 trust policy to a KMS key resource policy for SNS subscriptions." + }, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the EgressOnlyGateway resource is only created if private subnets are defined in the dual-stack VPC." + }, + "@aws-cdk/aws-ec2-alpha:useResourceIdForVpcV2Migration": { + "recommendedValue": false, + "explanation": "When enabled, use resource IDs for VPC V2 migration" + }, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined." + }, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK creates and manages loggroup for the lambda function" + }, + "@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault": { + "recommendedValue": true, + "explanation": "When enabled, Network Load Balancer will be created with a security group by default." + }, + "@aws-cdk/aws-stepfunctions-tasks:httpInvokeDynamicJsonPathEndpoint": { + "recommendedValue": true, + "explanation": "When enabled, allows using a dynamic apiEndpoint with JSONPath format in HttpInvoke tasks.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": { + "recommendedValue": true, + "explanation": "When enabled, ECS patterns will generate unique target group IDs to prevent conflicts during load balancer replacement" + } + } + } + } + }, + "minimumCliVersion": "2.1031.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/tree.json b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/tree.json new file mode 100644 index 0000000000000..c92ef3ed150f9 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-imagebuilder-component-s3-data":{"id":"aws-cdk-imagebuilder-component-s3-data","path":"aws-cdk-imagebuilder-component-s3-data","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"asset":{"id":"asset","path":"aws-cdk-imagebuilder-component-s3-data/asset","constructInfo":{"fqn":"aws-cdk-lib.aws_s3_assets.Asset","version":"0.0.0"},"children":{"Stage":{"id":"Stage","path":"aws-cdk-imagebuilder-component-s3-data/asset/Stage","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"AssetBucket":{"id":"AssetBucket","path":"aws-cdk-imagebuilder-component-s3-data/asset/AssetBucket","constructInfo":{"fqn":"aws-cdk-lib.aws_s3.BucketBase","version":"0.0.0","metadata":[]}}}},"S3AssetComponent":{"id":"S3AssetComponent","path":"aws-cdk-imagebuilder-component-s3-data/S3AssetComponent","constructInfo":{"fqn":"@aws-cdk/aws-imagebuilder-alpha.Component","version":"0.0.0","metadata":[]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-imagebuilder-component-s3-data/S3AssetComponent/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_imagebuilder.CfnComponent","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::ImageBuilder::Component","aws:cdk:cloudformation:props":{"name":"aws-cdk-imagebuilder-component-s3","platform":"Linux","uri":{"Fn::Join":["",["s3://",{"Fn::Sub":"cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"},"/bc0e810d66f3b8e9e6cfe276de3f128be221671559a8b6e657d1d97ace42bd52.yaml"]]},"version":"1.0.0"}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-imagebuilder-component-s3-data/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-imagebuilder-component-s3-data/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"ComponentTest":{"id":"ComponentTest","path":"ComponentTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"ComponentTest/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"ComponentTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"ComponentTest/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"ComponentTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.ts new file mode 100644 index 0000000000000..c1d83de6324aa --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/integ.s3.component.ts @@ -0,0 +1,23 @@ +import * as path from 'path'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as s3assets from 'aws-cdk-lib/aws-s3-assets'; +import * as imagebuilder from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-imagebuilder-component-s3-data'); + +const asset = new s3assets.Asset(stack, 'asset', { + path: path.join(__dirname, 'assets', 'component-data.yaml'), +}); + +new imagebuilder.Component(stack, 'S3AssetComponent', { + componentName: 'aws-cdk-imagebuilder-component-s3', + componentVersion: '1.0.0', + platform: imagebuilder.Platform.LINUX, + data: imagebuilder.ComponentData.fromS3(asset.bucket, asset.s3ObjectKey), +}); + +new integ.IntegTest(app, 'ComponentTest', { + testCases: [stack], +}); diff --git a/packages/@aws-cdk/aws-imagebuilder-alpha/test/os-version.test.ts b/packages/@aws-cdk/aws-imagebuilder-alpha/test/os-version.test.ts new file mode 100644 index 0000000000000..c35f6c398ea62 --- /dev/null +++ b/packages/@aws-cdk/aws-imagebuilder-alpha/test/os-version.test.ts @@ -0,0 +1,12 @@ +import { OSVersion, Platform } from '../lib'; + +describe('OS Version', () => { + test('should return the correct OS version string', () => { + expect(OSVersion.AMAZON_LINUX_2023.osVersion).toEqual('Amazon Linux 2023'); + }); + + test('should return the correct OS version string for a custom OS', () => { + const customOS = OSVersion.custom(Platform.LINUX, 'Custom OS'); + expect(customOS.osVersion).toEqual('Custom OS'); + }); +});