(eks, core): eks.Cluster has malformed IAM policy resource ARNs if clusterName is part-string, part token
- 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
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