Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ecs): new arn format not supported (under feature flag) #18140

Merged
merged 22 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3223be3
fix(ecs): new ARN format not recognized
jumic Dec 22, 2021
f5a3560
refactor duplicate code, add URL
jumic Dec 27, 2021
b5c9bf5
refactor from*ServiceArn methods
jumic Dec 27, 2021
a534380
Merge branch 'master' into ecs-new-arn-format
jumic Jan 25, 2022
dc8bcff
Merge branch 'master' into ecs-new-arn-format
madeline-k Mar 25, 2022
30546e6
switch fromServiceAttributes to use Construct from core. All v1 libra…
madeline-k Mar 25, 2022
010502e
Merge branch 'master' into ecs-new-arn-format
madeline-k Mar 31, 2022
2a2a047
Merge branch 'master' into ecs-new-arn-format
jumic Apr 24, 2022
728a094
add readme
jumic Apr 24, 2022
8f67295
use Construct from core
jumic Apr 24, 2022
5b145a7
Revert "use Construct from core"
jumic Apr 24, 2022
6a05966
use Construct from constructs
jumic Apr 24, 2022
dd295d8
Merge branch 'main' into ecs-new-arn-format
TheRealAmazonKendra Jun 13, 2022
92136f2
fix typo
TheRealAmazonKendra Jun 13, 2022
4db80e2
typo fix
TheRealAmazonKendra Jun 13, 2022
66b087f
Merge branch 'main' into ecs-new-arn-format
jumic Jun 21, 2022
c3097a7
Merge branch 'main' into ecs-new-arn-format
jumic Jun 21, 2022
afe21d9
Merge branch 'ecs-new-arn-format' of github.com:jumic/aws-cdk into ec…
jumic Jun 21, 2022
9caa1a5
Merge branch 'main' into ecs-new-arn-format
jumic Jul 25, 2022
a22ef04
Merge branch 'ecs-new-arn-format' of github.com:jumic/aws-cdk into ec…
jumic Jul 27, 2022
764d034
feature flag issue workaround
jumic Jul 27, 2022
f88e7fb
Merge branch 'main' into ecs-new-arn-format
mergify[bot] Jul 28, 2022
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
31 changes: 31 additions & 0 deletions packages/@aws-cdk/aws-ecs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,37 @@ There are two higher-level constructs available which include a load balancer fo
- `LoadBalancedFargateService`
- `LoadBalancedEc2Service`

### Import existing services

`Ec2Service` and `FargateService` provide methods to import existing EC2/Fargate services.
The ARN of the existing service has to be specified to import the service.

Since AWS has changed the [ARN format for ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids),
feature flag `@aws-cdk/aws-ecs:arnFormatIncludesClusterName` must be enabled to use the new ARN format.
The feature flag changes behavior for the entire CDK project. Therefore it is not possible to mix the old and the new format in one CDK project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly true, but we generally recommend to not do this inline and have zero (I think?) instructions on how to do it so I don't think I mind this note here.


```tss
declare const cluster: ecs.Cluster;

// Import service from EC2 service attributes
const service = ecs.Ec2Service.fromEc2ServiceAttributes(stack, 'EcsService', {
serviceArn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service',
cluster,
});

// Import service from EC2 service ARN
const service = ecs.Ec2Service.fromEc2ServiceArn(stack, 'EcsService', 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service');

// Import service from Fargate service attributes
const service = ecs.FargateService.fromFargateServiceAttributes(stack, 'EcsService', {
serviceArn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service',
cluster,
});

// Import service from Fargate service ARN
const service = ecs.FargateService.fromFargateServiceArn(stack, 'EcsService', 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service');
```

## Task Auto-Scaling

You can configure the task count of a service to match demand. Task auto-scaling is
Expand Down
29 changes: 26 additions & 3 deletions packages/@aws-cdk/aws-ecs/lib/base/from-service-attributes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ArnFormat, Resource, Stack } from '@aws-cdk/core';
import { ArnFormat, FeatureFlags, Fn, Resource, Stack, Token } from '@aws-cdk/core';
import { ECS_ARN_FORMAT_INCLUDES_CLUSTER_NAME } from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { IBaseService } from '../base/base-service';
import { ICluster } from '../cluster';
Expand Down Expand Up @@ -32,22 +33,25 @@ export function fromServiceAttributes(scope: Construct, id: string, attrs: Servi
throw new Error('You can only specify either serviceArn or serviceName.');
}

const newArnFormat = FeatureFlags.of(scope).isEnabled(ECS_ARN_FORMAT_INCLUDES_CLUSTER_NAME);

const stack = Stack.of(scope);
let name: string;
let arn: string;
if (attrs.serviceName) {
name = attrs.serviceName as string;
const resourceName = newArnFormat ? `${attrs.cluster.clusterName}/${attrs.serviceName}` : attrs.serviceName as string;
arn = stack.formatArn({
partition: stack.partition,
service: 'ecs',
region: stack.region,
account: stack.account,
resource: 'service',
resourceName: name,
resourceName,
});
} else {
arn = attrs.serviceArn as string;
name = stack.splitArn(arn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
name = extractServiceNameFromArn(scope, arn);
}
class Import extends Resource implements IBaseService {
public readonly serviceArn = arn;
Expand All @@ -58,3 +62,22 @@ export function fromServiceAttributes(scope: Construct, id: string, attrs: Servi
environmentFromArn: arn,
});
}

export function extractServiceNameFromArn(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(2, lastComponents);
} else {
return stack.splitArn(arn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
}
} else {
const resourceName = stack.splitArn(arn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
const resourceNameSplit = resourceName.split('/');
return resourceNameSplit.length === 1 ? resourceName : resourceNameSplit[1];
}
}
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as ec2 from '@aws-cdk/aws-ec2';
import { ArnFormat, Lazy, Resource, Stack } from '@aws-cdk/core';
import { Lazy, Resource, Stack } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType } from '../base/base-service';
import { fromServiceAttributes } from '../base/from-service-attributes';
import { fromServiceAtrributes, extractServiceNameFromArn } 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 @@ -128,7 +128,7 @@ 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 = Stack.of(scope).splitArn(ec2ServiceArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
public readonly serviceName = extractServiceNameFromArn(this, ec2ServiceArn);
}
return new Import(scope, id);
}
Expand Down
5 changes: 2 additions & 3 deletions packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as ec2 from '@aws-cdk/aws-ec2';
import * as cdk from '@aws-cdk/core';
import { ArnFormat } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType } from '../base/base-service';
import { fromServiceAttributes } from '../base/from-service-attributes';
import { fromServiceAtrributes, extractServiceNameFromArn } from '../base/from-service-attributes';
import { TaskDefinition } from '../base/task-definition';
import { ICluster } from '../cluster';

Expand Down Expand Up @@ -105,7 +104,7 @@ 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 = cdk.Stack.of(scope).splitArn(fargateServiceArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName as string;
public readonly serviceName = extractServiceNameFromArn(this, fargateServiceArn);
}
return new Import(scope, id);
}
Expand Down
Loading