Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ export class ImportedTaskDefinition extends Resource implements IEc2TaskDefiniti
*/
readonly _taskRole?: IRole;

public get taskDefinitionRef() {
return {
taskDefinitionArn: this.taskDefinitionArn,
};
}

constructor(scope: Construct, id: string, props: ImportedTaskDefinitionProps) {
super(scope, id);
// Enhanced CDK Analytics Telemetry
Expand Down
17 changes: 16 additions & 1 deletion packages/aws-cdk-lib/aws-ecs/lib/base/base-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ValidationError,
} from '../../../core';
import * as cxapi from '../../../cx-api';
import { IServiceRef } from '../../../interfaces/generated/aws-ecs-interfaces.generated';
import { RegionInfo } from '../../../region-info';
import { IAlternateTarget } from '../alternate-target-configuration';
import {
Expand All @@ -42,7 +43,7 @@ import { LogDriver, LogDriverConfig } from '../log-drivers/log-driver';
/**
* The interface for a service.
*/
export interface IService extends IResource {
export interface IService extends IResource, IServiceRef {
/**
* The Amazon Resource Name (ARN) of the service.
*
Expand Down Expand Up @@ -603,6 +604,13 @@ export abstract class BaseService extends Resource
public readonly serviceArn = serviceArn;
public readonly serviceName = serviceName;
public readonly cluster = cluster;

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this.cluster.clusterName,
};
}
}

return new Import(scope, id, {
Expand Down Expand Up @@ -640,6 +648,13 @@ export abstract class BaseService extends Resource
*/
public readonly cluster: ICluster;

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this.cluster.clusterName,
};
}

/**
* The details of the AWS Cloud Map service.
*/
Expand Down
29 changes: 29 additions & 0 deletions packages/aws-cdk-lib/aws-ecs/lib/base/from-service-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ export function fromServiceAttributes(scope: Construct, id: string, attrs: Servi
public readonly serviceArn = arn;
public readonly serviceName = name;
public readonly cluster = attrs.cluster;

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this.cluster.clusterName,
};
}
}
return new Import(scope, id, {
environmentFromArn: arn,
Expand All @@ -81,3 +88,25 @@ export function extractServiceNameFromArn(scope: Construct, arn: string): string
return resourceNameSplit.length === 1 ? resourceName : resourceNameSplit[1];
}
}

export function extractClusterNameFromArn(scope: Construct, arn: string): string {
const newArnFormat = FeatureFlags.of(scope).isEnabled(ECS_ARN_FORMAT_INCLUDES_CLUSTER_NAME);
const stack = Stack.of(scope);

if (Token.isUnresolved(arn)) {
if (newArnFormat) {
const components = Fn.split(':', arn);
const lastComponents = Fn.split('/', Fn.select(5, components));
return Fn.select(1, lastComponents);
} else {
throw new ValidationError('Cannot extract cluster name from service ARN in old format when ARN is unresolved', scope);
}
} else {
const resourceName = stack.splitArn(arn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
const resourceNameSplit = resourceName.split('/');
if (resourceNameSplit.length === 1) {
throw new ValidationError(`Cannot extract cluster name from service ARN: ${arn}. The ARN is in the old format which does not include the cluster name.`, scope);
}
return resourceNameSplit[0];
}
}
9 changes: 8 additions & 1 deletion packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as iam from '../../../aws-iam';
import { IResource, Lazy, Names, PhysicalName, Resource, UnscopedValidationError, ValidationError } from '../../../core';
import { addConstructMetadata, MethodMetadata } from '../../../core/lib/metadata-resource';
import { propertyInjectable } from '../../../core/lib/prop-injectable';
import { ITaskDefinitionRef } from '../../../interfaces/generated/aws-ecs-interfaces.generated';
import { IAlternateTarget } from '../alternate-target-configuration';
import { ContainerDefinition, ContainerDefinitionOptions, PortMapping, Protocol } from '../container-definition';
import { CfnTaskDefinition, CfnTaskDefinitionProps } from '../ecs.generated';
Expand All @@ -17,7 +18,7 @@ import { RuntimePlatform } from '../runtime-platform';
/**
* The interface for all task definitions.
*/
export interface ITaskDefinition extends IResource {
export interface ITaskDefinition extends IResource, ITaskDefinitionRef {
/**
* ARN of this task definition
* @attribute
Expand Down Expand Up @@ -302,6 +303,12 @@ abstract class TaskDefinitionBase extends Resource implements ITaskDefinition {
public abstract readonly taskRole: iam.IRole;
public abstract readonly executionRole?: iam.IRole;

public get taskDefinitionRef() {
return {
taskDefinitionArn: this.taskDefinitionArn,
};
}

/**
* Return true if the task definition can be run on an EC2 cluster
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-ecs/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1782,8 +1782,8 @@ export class ManagedInstancesCapacityProvider extends Construct implements ec2.I
* Associates the capacity provider with the specified cluster.
* This method is called by the cluster when adding the capacity provider.
*/
public bind(cluster: ICluster): void {
this.capacityProvider.clusterName = cluster.clusterName;
public bind(cluster: IClusterRef): void {
this.capacityProvider.clusterName = cluster.clusterRef.clusterName;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as iam from '../../../aws-iam';
import * as kms from '../../../aws-kms';
import * as lambda from '../../../aws-lambda';
import * as cdk from '../../../core';
import { ICluster } from '../cluster';
import { IClusterRef } from '../ecs.generated';

// Reference for the source in this package:
//
Expand All @@ -25,7 +25,7 @@ export interface InstanceDrainHookProps {
/**
* The cluster on which tasks have been scheduled
*/
cluster: ICluster;
cluster: IClusterRef;

/**
* How many seconds to give tasks to drain before the instance is terminated anyway
Expand Down Expand Up @@ -67,7 +67,7 @@ export class InstanceDrainHook extends Construct {
// up to a maximum of 15 minutes.
timeout: cdk.Duration.seconds(Math.min(drainTime.toSeconds() + 10, 900)),
environment: {
CLUSTER: props.cluster.clusterName,
CLUSTER: props.cluster.clusterRef.clusterName,
},
});

Expand Down Expand Up @@ -101,7 +101,7 @@ export class InstanceDrainHook extends Construct {
actions: ['ecs:DescribeContainerInstances', 'ecs:DescribeTasks'],
resources: ['*'],
conditions: {
ArnEquals: { 'ecs:cluster': props.cluster.clusterArn },
ArnEquals: { 'ecs:cluster': props.cluster.clusterRef.clusterArn },
},
}));

Expand All @@ -112,7 +112,7 @@ export class InstanceDrainHook extends Construct {
'ecs:SubmitContainerStateChange',
'ecs:SubmitTaskStateChange',
],
resources: [props.cluster.clusterArn],
resources: [props.cluster.clusterRef.clusterArn],
}));

// Restrict the container-instance operations to the ECS Cluster
Expand All @@ -122,7 +122,7 @@ export class InstanceDrainHook extends Construct {
'ecs:ListTasks',
],
conditions: {
ArnEquals: { 'ecs:cluster': props.cluster.clusterArn },
ArnEquals: { 'ecs:cluster': props.cluster.clusterRef.clusterArn },
},
resources: ['*'],
}));
Expand Down
12 changes: 10 additions & 2 deletions packages/aws-cdk-lib/aws-ecs/lib/ec2/ec2-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { addConstructMetadata, MethodMetadata } from '../../../core/lib/metadata
import { propertyInjectable } from '../../../core/lib/prop-injectable';
import { AvailabilityZoneRebalancing } from '../availability-zone-rebalancing';
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType } from '../base/base-service';
import { fromServiceAttributes, extractServiceNameFromArn } from '../base/from-service-attributes';
import { fromServiceAttributes, extractServiceNameFromArn, extractClusterNameFromArn } from '../base/from-service-attributes';
import { NetworkMode, TaskDefinition } from '../base/task-definition';
import { ICluster } from '../cluster';
import { CfnService } from '../ecs.generated';
Expand Down Expand Up @@ -150,7 +150,15 @@ export class Ec2Service extends BaseService implements IEc2Service {
public static fromEc2ServiceArn(scope: Construct, id: string, ec2ServiceArn: string): IEc2Service {
class Import extends Resource implements IEc2Service {
public readonly serviceArn = ec2ServiceArn;
public readonly serviceName = extractServiceNameFromArn(this, ec2ServiceArn);
public readonly serviceName = extractServiceNameFromArn(scope, ec2ServiceArn);
private readonly _clusterName = extractClusterNameFromArn(scope, ec2ServiceArn);

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this._clusterName,
};
}
}
return new Import(scope, id);
}
Expand Down
10 changes: 9 additions & 1 deletion packages/aws-cdk-lib/aws-ecs/lib/external/external-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ArnFormat, Resource, Stack, Annotations, ValidationError } from '../../
import { addConstructMetadata, MethodMetadata } from '../../../core/lib/metadata-resource';
import { propertyInjectable } from '../../../core/lib/prop-injectable';
import { AssociateCloudMapServiceOptions, BaseService, BaseServiceOptions, CloudMapOptions, DeploymentControllerType, EcsTarget, IBaseService, IEcsLoadBalancerTarget, IService, LaunchType, PropagatedTagSource } from '../base/base-service';
import { fromServiceAttributes } from '../base/from-service-attributes';
import { fromServiceAttributes, extractClusterNameFromArn } from '../base/from-service-attributes';
import { ScalableTaskCount } from '../base/scalable-task-count';
import { Compatibility, LoadBalancerTargetOptions, TaskDefinition } from '../base/task-definition';
import { ICluster } from '../cluster';
Expand Down Expand Up @@ -91,6 +91,14 @@ export class ExternalService extends BaseService implements IExternalService {
class Import extends Resource implements IExternalService {
public readonly serviceArn = externalServiceArn;
public readonly serviceName = Stack.of(scope).splitArn(externalServiceArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
private readonly _clusterName = extractClusterNameFromArn(scope, externalServiceArn);

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this._clusterName,
};
}
}
return new Import(scope, id);
}
Expand Down
12 changes: 10 additions & 2 deletions packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { addConstructMetadata, MethodMetadata } from '../../../core/lib/metadata
import { propertyInjectable } from '../../../core/lib/prop-injectable';
import { AvailabilityZoneRebalancing } from '../availability-zone-rebalancing';
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType } from '../base/base-service';
import { fromServiceAttributes, extractServiceNameFromArn } from '../base/from-service-attributes';
import { fromServiceAttributes, extractServiceNameFromArn, extractClusterNameFromArn } from '../base/from-service-attributes';
import { TaskDefinition } from '../base/task-definition';
import { ICluster } from '../cluster';

Expand Down Expand Up @@ -128,7 +128,15 @@ export class FargateService extends BaseService implements IFargateService {
public static fromFargateServiceArn(scope: Construct, id: string, fargateServiceArn: string): IFargateService {
class Import extends cdk.Resource implements IFargateService {
public readonly serviceArn = fargateServiceArn;
public readonly serviceName = extractServiceNameFromArn(this, fargateServiceArn);
public readonly serviceName = extractServiceNameFromArn(scope, fargateServiceArn);
private readonly _clusterName = extractClusterNameFromArn(scope, fargateServiceArn);

public get serviceRef() {
return {
serviceArn: this.serviceArn,
cluster: this._clusterName,
};
}
}
return new Import(scope, id);
}
Expand Down
Loading