Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ee13236
feat: new resource reference interfaces
otaviomacedo Jul 22, 2025
9dd8eba
Oops
otaviomacedo Jul 22, 2025
bef585b
Updated snapshot
otaviomacedo Jul 23, 2025
d680262
Merge branch 'main' into otaviom/resource-ref-interface
otaviomacedo Jul 23, 2025
3713f10
itemId
otaviomacedo Jul 23, 2025
1dcfbd8
feat: add ARN attribute to common resource interface
otaviomacedo Jul 23, 2025
b00f7bc
Removed debug code
otaviomacedo Jul 23, 2025
accce40
Skip composite primary identifiers
otaviomacedo Aug 7, 2025
f896e87
Merge branch 'main' into otaviom/resource-ref-interface
otaviomacedo Aug 8, 2025
f750c46
Merge branch 'main' into otaviom/resource-ref-interface
otaviomacedo Aug 11, 2025
9f96725
Revert scripts/prioritization/assign-r5-priority.js
otaviomacedo Aug 11, 2025
62bdc76
Remove `Construct` from the parents of the generated interfaces
otaviomacedo Aug 11, 2025
40fb819
Exclude the 'construct-interface-extends-iconstruct' rule for the ICf…
otaviomacedo Aug 12, 2025
9a79ff7
Add "@aws-cdk/aws-pipes-sources-alpha" to example dependencies
otaviomacedo Aug 12, 2025
d8da50c
Addressed comments
otaviomacedo Aug 12, 2025
a60fbf9
Updated interface names
otaviomacedo Aug 12, 2025
8099618
Removed awslint exclusions
otaviomacedo Aug 12, 2025
f0d857b
Removed unused code
otaviomacedo Aug 12, 2025
27d75ee
Rewrite to an indirecting interface
rix0rrr Aug 19, 2025
e2fde34
Naming fixes
rix0rrr Aug 19, 2025
585defe
Final touches
rix0rrr Aug 19, 2025
b3dd9f4
Merge remote-tracking branch 'origin/main' into otaviom/resource-ref-…
rix0rrr Aug 19, 2025
e9df322
Update tests
rix0rrr Aug 19, 2025
d8825af
Updates
rix0rrr Aug 20, 2025
0e51961
Add IConstruct
rix0rrr Aug 25, 2025
6b1941e
NameRef -> NameReference in ResourceClass
otaviomacedo Aug 29, 2025
892c88f
Merge branch 'main' into otaviom/resource-ref-interface
otaviomacedo Sep 1, 2025
601b8d5
Experimental
otaviomacedo Sep 1, 2025
345907c
Update snapshots
otaviomacedo Sep 1, 2025
9e82000
feat: implement new shared interfaces for L2 resources (ref-interface…
rix0rrr Sep 2, 2025
5f9fb8c
feat: update references to use new shared resource interface (ref-int…
otaviomacedo Sep 2, 2025
73d1b33
Merge branch 'main' into otaviom/resource-ref-interface
rix0rrr Sep 3, 2025
dc8c47b
Merge branch 'main' into otaviom/resource-ref-interface
mergify[bot] Sep 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import * as path from 'path';
import * as codepipeline from 'aws-cdk-lib/aws-codepipeline';
import * as elasticbeanstalk from 'aws-cdk-lib/aws-elasticbeanstalk';
import * as iam from 'aws-cdk-lib/aws-iam';
import { IManagedPolicy, ManagedPolicyReference } from 'aws-cdk-lib/aws-iam';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as deploy from 'aws-cdk-lib/aws-s3-deployment';
import { App, Fn, RemovalPolicy, Stack } from 'aws-cdk-lib';
import { App, Fn, RemovalPolicy, Stack, UnscopedValidationError } from 'aws-cdk-lib';
import * as integ from '@aws-cdk/integ-tests-alpha';
import * as cpactions from 'aws-cdk-lib/aws-codepipeline-actions';
import { Node } from 'constructs';

/**
* To validate that the deployment actually succeeds, perform the following actions:
Expand Down Expand Up @@ -43,32 +45,36 @@ const artifact = new deploy.BucketDeployment(stack, 'DeployApp', {
extract: false,
});

function makePolicy(arn: string): IManagedPolicy {
return {
managedPolicyArn: arn,
get managedPolicyRef(): ManagedPolicyReference {
return {
policyArn: this.managedPolicyArn,
};
},
get node(): Node {
throw new UnscopedValidationError('The result of fromAwsManagedPolicyName can not be used in this API');
},
};
}

const serviceRole = new iam.Role(stack, 'service-role', {
roleName: 'codepipeline-elasticbeanstalk-action-test-serivce-role',
assumedBy: new iam.ServicePrincipal('elasticbeanstalk.amazonaws.com'),
managedPolicies: [
{
managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth',
},
{
managedPolicyArn: 'arn:aws:iam::aws:policy/AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy',
},
makePolicy('arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth'),
makePolicy('arn:aws:iam::aws:policy/AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy'),
],
});

const instanceProfileRole = new iam.Role(stack, 'instance-profile-role', {
roleName: 'codepipeline-elasticbeanstalk-action-test-instance-profile-role',
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
{
managedPolicyArn: 'arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier',
},
{
managedPolicyArn: 'arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker',
},
{
managedPolicyArn: 'arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier',
},
makePolicy('arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier'),
makePolicy('arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker'),
makePolicy('arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier'),
],
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
import * as databrew from 'aws-cdk-lib/aws-databrew';
import * as iam from 'aws-cdk-lib/aws-iam';
import { IManagedPolicy, ManagedPolicyReference } from 'aws-cdk-lib/aws-iam';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as cdk from 'aws-cdk-lib';
import { UnscopedValidationError } from 'aws-cdk-lib';
import { GlueDataBrewStartJobRun } from 'aws-cdk-lib/aws-stepfunctions-tasks';
import { Node } from 'constructs';

/*
* Stack verification steps:
* * aws stepfunctions start-execution --state-machine-arn <deployed state machine arn> : should return execution arn
* * aws stepfunctions describe-execution --execution-arn <exection-arn generated before> : should return status as SUCCEEDED
*/

function makePolicy(arn: string): IManagedPolicy {
return {
managedPolicyArn: arn,
get managedPolicyRef(): ManagedPolicyReference {
return {
policyArn: this.managedPolicyArn,
};
},
get node(): Node {
throw new UnscopedValidationError('The result of fromAwsManagedPolicyName can not be used in this API');
},
};
}

class GlueDataBrewJobStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props: cdk.StackProps = {}) {
super(scope, id, props);
Expand All @@ -22,9 +39,9 @@ class GlueDataBrewJobStack extends cdk.Stack {
});

const role = new iam.Role(this, 'DataBrew Role', {
managedPolicies: [{
managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSGlueDataBrewServiceRole',
}],
managedPolicies: [
makePolicy('arn:aws:iam::aws:policy/service-role/AWSGlueDataBrewServiceRole'),
],
path: '/',
assumedBy: new iam.ServicePrincipal('databrew.amazonaws.com'),
inlinePolicies: {
Expand Down
26 changes: 24 additions & 2 deletions packages/@aws-cdk/aws-ec2-alpha/lib/subnet-v2.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { Resource, Names, Lazy, Tags, Token, ValidationError, UnscopedValidationError } from 'aws-cdk-lib';
import { CfnSubnet, CfnSubnetRouteTableAssociation, INetworkAcl, IRouteTable, ISubnet, NetworkAcl, SubnetNetworkAclAssociation, SubnetType } from 'aws-cdk-lib/aws-ec2';
import { Lazy, Names, Resource, Tags, Token, UnscopedValidationError, ValidationError } from 'aws-cdk-lib';
import {
CfnSubnet,
CfnSubnetRouteTableAssociation,
INetworkAcl,
IRouteTable,
ISubnet,
NetworkAcl,
SubnetNetworkAclAssociation,
SubnetType,
} from 'aws-cdk-lib/aws-ec2';
import { Construct, DependencyGroup, IDependable } from 'constructs';
import { IVpcV2 } from './vpc-v2-base';
import { CidrBlock, CidrBlockIpv6, defaultSubnetName } from './util';
import { RouteTable } from './route';
import { addConstructMetadata, MethodMetadata } from 'aws-cdk-lib/core/lib/metadata-resource';
import { propertyInjectable } from 'aws-cdk-lib/core/lib/prop-injectable';
import { SubnetReference } from 'aws-cdk-lib/aws-ec2/lib/ec2.generated';

/**
* Interface to define subnet CIDR
Expand Down Expand Up @@ -194,6 +204,12 @@ export class SubnetV2 extends Resource implements ISubnetV2 {
*/
public readonly routeTable: IRouteTable = { routeTableId: attrs.routeTableId! };

public get subnetRef(): SubnetReference {
return {
subnetId: this.subnetId,
};
}

/**
* Associate a Network ACL with this subnet
* Required here since it is implemented in the ISubnetV2
Expand Down Expand Up @@ -245,6 +261,12 @@ export class SubnetV2 extends Resource implements ISubnetV2 {
*/
public readonly ipv6CidrBlock?: string;

public get subnetRef(): SubnetReference {
return {
subnetId: this.subnetId,
};
}

/**
* The type of subnet (public or private) that this subnet represents.
* @attribute SubnetType
Expand Down
48 changes: 44 additions & 4 deletions packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
import { Aws, Resource, Annotations, ValidationError } from 'aws-cdk-lib';
import { IVpc, ISubnet, SubnetSelection, SelectedSubnets, EnableVpnGatewayOptions, VpnGateway, VpnConnectionType, CfnVPCGatewayAttachment, CfnVPNGatewayRoutePropagation, VpnConnectionOptions, VpnConnection, ClientVpnEndpointOptions, ClientVpnEndpoint, InterfaceVpcEndpointOptions, InterfaceVpcEndpoint, GatewayVpcEndpointOptions, GatewayVpcEndpoint, FlowLogOptions, FlowLog, FlowLogResourceType, SubnetType, SubnetFilter } from 'aws-cdk-lib/aws-ec2';
import { Annotations, Aws, Resource, ValidationError } from 'aws-cdk-lib';
import {
CfnVPCGatewayAttachment,
CfnVPNGatewayRoutePropagation,
ClientVpnEndpoint,
ClientVpnEndpointOptions,
EnableVpnGatewayOptions,
FlowLog,
FlowLogOptions,
FlowLogResourceType,
GatewayVpcEndpoint,
GatewayVpcEndpointOptions,
InterfaceVpcEndpoint,
InterfaceVpcEndpointOptions,
ISubnet,
IVpc,
SelectedSubnets,
SubnetFilter,
SubnetSelection,
SubnetType,
VpnConnection,
VpnConnectionOptions,
VpnConnectionType,
VpnGateway,
} from 'aws-cdk-lib/aws-ec2';
import { allRouteTableIds, flatten, subnetGroupNameFromConstructId } from './util';
import { IDependable, Dependable, IConstruct, DependencyGroup } from 'constructs';
import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, NatGatewayOptions, Route, VPCPeeringConnection, VPCPeeringConnectionOptions, VPNGatewayV2 } from './route';
import { Dependable, DependencyGroup, IConstruct, IDependable } from 'constructs';
import {
EgressOnlyInternetGateway,
InternetGateway,
NatConnectivityType,
NatGateway,
NatGatewayOptions,
Route,
VPCPeeringConnection,
VPCPeeringConnectionOptions,
VPNGatewayV2,
} from './route';
import { ISubnetV2 } from './subnet-v2';
import { AccountPrincipal, Effect, PolicyStatement, Role } from 'aws-cdk-lib/aws-iam';
import { IVPCCidrBlock } from './vpc-v2';
import { VPCReference } from 'aws-cdk-lib/aws-ec2/lib/ec2.generated';

/**
* Options to define EgressOnlyInternetGateway for VPC
Expand Down Expand Up @@ -327,6 +361,12 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 {
};
}

public get vpcRef(): VPCReference {
return {
vpcId: this.vpcId,
};
}

/**
* Adds a VPN Gateway to this VPC
* @deprecated use enableVpnGatewayV2 for compatibility with VPCV2.Route
Expand Down
10 changes: 8 additions & 2 deletions packages/aws-cdk-lib/aws-apigateway/lib/api-key.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Construct } from 'constructs';
import { CfnApiKey } from './apigateway.generated';
import { ApiKeyReference, CfnApiKey, IApiKeyRef } from './apigateway.generated';
import { ResourceOptions } from './resource';
import { IRestApi } from './restapi';
import { IStage } from './stage';
Expand All @@ -14,7 +14,7 @@ import { propertyInjectable } from '../../core/lib/prop-injectable';
* API keys are alphanumeric string values that you distribute to
* app developer customers to grant access to your API
*/
export interface IApiKey extends IResourceBase {
export interface IApiKey extends IResourceBase, IApiKeyRef {
/**
* The API key ID.
* @attribute
Expand Down Expand Up @@ -138,6 +138,12 @@ abstract class ApiKeyBase extends Resource implements IApiKey {
resourceArns: [this.keyArn],
});
}

public get apiKeyRef(): ApiKeyReference {
return {
apiKeyId: this.keyId,
};
}
}

/**
Expand Down
17 changes: 14 additions & 3 deletions packages/aws-cdk-lib/aws-apigateway/lib/domain-name.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Construct } from 'constructs';
import { CfnDomainName } from './apigateway.generated';
import { CfnDomainName, DomainNameReference, IDomainNameRef } from './apigateway.generated';
import { BasePathMapping, BasePathMappingOptions } from './base-path-mapping';
import { EndpointType, IRestApi } from './restapi';
import { IStage } from './stage';
import * as apigwv2 from '../../aws-apigatewayv2';
import * as acm from '../../aws-certificatemanager';
import { IBucket } from '../../aws-s3';
import { IResource, Names, Resource, Token } from '../../core';
import { Arn, IResource, Names, Resource, Stack, Token } from '../../core';
import { ValidationError } from '../../core/lib/errors';
import { addConstructMetadata, MethodMetadata } from '../../core/lib/metadata-resource';
import { propertyInjectable } from '../../core/lib/prop-injectable';
Expand Down Expand Up @@ -94,7 +94,7 @@ export interface DomainNameProps extends DomainNameOptions {
readonly mapping?: IRestApi;
}

export interface IDomainName extends IResource {
export interface IDomainName extends IResource, IDomainNameRef {
/**
* The domain name (e.g. `example.com`)
*
Expand Down Expand Up @@ -132,12 +132,22 @@ export class DomainName extends Resource implements IDomainName {
public readonly domainName = attrs.domainName;
public readonly domainNameAliasDomainName = attrs.domainNameAliasTarget;
public readonly domainNameAliasHostedZoneId = attrs.domainNameAliasHostedZoneId;

public readonly domainNameRef = {
domainName: this.domainName,
domainNameArn: Arn.format({
service: 'apigateway',
resource: 'domainnames',
resourceName: attrs.domainName,
}, Stack.of(scope)),
};
}

return new Import(scope, id);
}

public readonly domainName: string;
public readonly domainNameRef: DomainNameReference;
public readonly domainNameAliasDomainName: string;
public readonly domainNameAliasHostedZoneId: string;
private readonly basePaths = new Set<string | undefined>();
Expand Down Expand Up @@ -168,6 +178,7 @@ export class DomainName extends Resource implements IDomainName {
});

this.domainName = resource.ref;
this.domainNameRef = resource.domainNameRef;

this.domainNameAliasDomainName = edge
? resource.attrDistributionDomainName
Expand Down
24 changes: 22 additions & 2 deletions packages/aws-cdk-lib/aws-apigateway/lib/gateway-response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Construct } from 'constructs';
import { CfnGatewayResponse, CfnGatewayResponseProps } from './apigateway.generated';
import {
CfnGatewayResponse,
CfnGatewayResponseProps,
GatewayResponseReference,
IGatewayResponseRef,
} from './apigateway.generated';
import { IRestApi } from './restapi';
import { IResource, Resource } from '../../core';
import { addConstructMetadata } from '../../core/lib/metadata-resource';
Expand All @@ -8,7 +13,7 @@ import { propertyInjectable } from '../../core/lib/prop-injectable';
/**
* Represents gateway response resource.
*/
export interface IGatewayResponse extends IResource {
export interface IGatewayResponse extends IResource, IGatewayResponseRef {
}

/**
Expand Down Expand Up @@ -61,6 +66,20 @@ export class GatewayResponse extends Resource implements IGatewayResponse {
/** Uniquely identifies this class. */
public static readonly PROPERTY_INJECTION_ID: string = 'aws-cdk-lib.aws-apigateway.GatewayResponse';

/**
* Reference an existing GatewayResponse given a gateway response ID.
*/
public static fromGatewayResponseId(scope: Construct, id: string, gatewayResponseId: string): IGatewayResponse {
class Import extends Resource implements IGatewayResponse {
public readonly gatewayResponseRef = {
gatewayResponseId: gatewayResponseId,
};
}
return new Import(scope, id);
}

public readonly gatewayResponseRef: GatewayResponseReference;

constructor(scope: Construct, id: string, props: GatewayResponseProps) {
super(scope, id);
// Enhanced CDK Analytics Telemetry
Expand All @@ -86,6 +105,7 @@ export class GatewayResponse extends Resource implements IGatewayResponse {
});
}

this.gatewayResponseRef = resource.gatewayResponseRef;
this.node.defaultChild = resource;
}

Expand Down
13 changes: 10 additions & 3 deletions packages/aws-cdk-lib/aws-apigateway/lib/resource.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Construct } from 'constructs';
import { CfnResource, CfnResourceProps } from './apigateway.generated';
import { CfnResource, CfnResourceProps, IResourceRef, ResourceReference } from './apigateway.generated';
import { Cors, CorsOptions } from './cors';
import { Integration } from './integration';
import { MockIntegration } from './integrations';
import { Method, MethodOptions, AuthorizationType } from './method';
import { AuthorizationType, Method, MethodOptions } from './method';
import { IRestApi, RestApi } from './restapi';
import { IResource as IResourceBase, Resource as ResourceConstruct } from '../../core';
import { ValidationError } from '../../core/lib/errors';
import { addConstructMetadata, MethodMetadata } from '../../core/lib/metadata-resource';
import { propertyInjectable } from '../../core/lib/prop-injectable';

export interface IResource extends IResourceBase {
export interface IResource extends IResourceBase, IResourceRef {
/**
* The parent of this resource or undefined for the root resource.
*/
Expand Down Expand Up @@ -383,6 +383,13 @@ export abstract class ResourceBase extends ResourceConstruct implements IResourc
public get url(): string {
return this.restApi.urlForPath(this.path);
}

public get resourceRef(): ResourceReference {
return {
resourceId: this.resourceId,
restApiId: this.api.restApiId,
};
}
}

/**
Expand Down
Loading
Loading