aws / aws/aws-cdk

(eks, core): eks.Cluster has malformed IAM policy resource ARNs if clusterName is part-string, part token

Open
#18,540 2 comments 1 reaction 0 assignees View on GitHub
@aws-cdk/core bug effort/medium investigating p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### What is the problem?

When passed a part-string, part-token `clusterName` like `foo-${param.stringValue}`, the `eks.Cluster` constructor incorrectly generates the resource ARNs in the adminRole policies. Specifically, the resourceName ARN component is resolving as `[object Object]`, as in `":eks:us-east-1:112233445566:cluster/[object Object]"`. In contrast, the `Custom::AWSCDK-EKS-Cluster` `name` is resolving as expected with a `Fn.Join`. Prompted by this [Stack Overflow](https://stackoverflow.com/questions/70753915/eks-cluster-name-issue-cdk) question.

### Reproduction Steps

Define a part-string, part-token `clusterName`:

```typescript
export class ClusterNameMinimalStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);

const param = ssm.StringParameter.fromStringParameterName(this,'SampleParam','/cdk-bootstrap/hnb659fds/version');

new eks.Cluster(this, 'cluster', {
version: eks.KubernetesVersion.V1_19,
clusterName: cdk.Fn.sub('eks-${param}', { param: param.stringValue });
});
}
}
```

### What did you expect to happen?

Assert that `[object Object]` does not appear in the template:

```typescript
test('Demonstrate that adminRole resource ARNs have [object Object] resourceName components', () => {
const app = new cdk.App();
const eksStack = new ClusterNameMinimalStack(app, 'TestStack', {env: { account: '112233445566', region: 'us-east-1' },});
const template = Template.fromStack(eksStack);

// matches if the ARN has [object Object] in the string
const badClusterArnMatch = JSON.stringify(template.toJSON()).match(/:eks:us-east-1:112233445566:(?:cluster)|(?:fargateprofile)\/\[object Object\]/g) ?? [];

expect(badClusterArnMatch.length).toBe(0); // FAILS -> 3 bad references
});
```

### What actually happened?

Output template has 3 malformed policy resource ARNs with `[object Object]`. Here's one:

```json
"clusterCreationRoleDefaultPolicy69503D11": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Effect": "Allow",
"Resource": [
{"Fn::Join": ["",["arn:",{"Ref": "AWS::Partition"},":eks:us-east-1:112233445566:cluster/[object Object]"]]},
```

### CDK CLI Version

2.8.0

### Framework Version

2.8.0

### Node.js Version

14

### OS

osx

### Language

Typescript

### Language Version

4.5.4

### Other information

The ARNs are being produced in the `ClusterResource` construct ([source](https://github.com/aws/aws-cdk/blob/9d1b2c7b1f0147089f912c32a61d7ba86edb543c/packages/%40aws-cdk/aws-eks/lib/cluster-resource.ts#L139-L146)).

```typescript
const resourceArns = Lazy.list({
produce: () => {
const arn = stack.formatArn(clusterArnComponents(stack.resolve(props.name)));
return stack.resolve(props.name)
? [arn, `${arn}/*`] // see https://github.com/aws/aws-cdk/issues/6060
: ['*'];
},
});
```

The root cause may lie with `Stack.resolve` rather than `eks`. Some good and bad test examples:

```typescript
const hybridStringToken = cdk.Fn.sub('eks-${param}', { param: param.stringValue });

// OK
new cdk.CfnOutput(this, 'HybridOK', {
value: this.formatArn(clusterArnComponents(hybridStringToken)),
});

// BAD - ":eks:us-east-1:112233445566:cluster/[object Object]"
new cdk.CfnOutput(this, 'ResolvedHybridBAD', {
value: this.formatArn(clusterArnComponents(this.resolve(hybridStringToken))),
});

// BAD - being lazy does not matter
new cdk.CfnOutput(this, 'ResolvedLazyHybridArnBAD', {
value: cdk.Lazy.string({
produce: () => {
const resolvedHybrid = cdk.Stack.of(this).resolve(hybridStringToken);
return this.formatArn(clusterArnComponents(resolvedHybrid));
},
}),
});
```

Contributor guide

Open the contributing guide

Research direction

Start in packages/@aws-cdk/aws-eks/lib/cluster-resource.ts around lines 139-146, then reproduce the provided ClusterNameMinimalStack and compare the direct, resolved, and lazy resolve/formatArn examples. Trace how the part-string token becomes the resource ARN, and verify completion by asserting that the synthesized template contains no [object Object] ARN components.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
authorization, cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.