in source/lib/msk-client.ts [84:157]
private createInstanceProfile(clusterName: string): iam.CfnInstanceProfile {
const role = new iam.Role(this, 'Role', {
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')
});
const ssmPolicy = new iam.Policy(this, 'SessionManagerPolicy', {
statements: [new iam.PolicyStatement({
resources: ['*'],
actions: [
'ssm:UpdateInstanceInformation',
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel'
]
})]
});
this.addW12Suppression(ssmPolicy, 'Session Manager actions do not support resource level permissions');
ssmPolicy.attachToRole(role);
const mskPolicy = new iam.Policy(this, 'MskPolicy', {
statements: [
new iam.PolicyStatement({
sid: 'ClusterMetadata',
resources: ['*'],
actions: ['kafka:DescribeCluster', 'kafka:GetBootstrapBrokers']
}),
// For topics and groups, the resources contain "/*/*":
// - The first one refers to the cluster UUID
// - The second one refers to the topic / group name
// Since this is meant to be a generic client, we use "*" so that this instance can create any topics or groups.
new iam.PolicyStatement({
sid: 'ClusterAPIs',
resources: [
// The cluster ARN in MSK contains an UUID, which is only available after the cluster is created.
// Example: arn:${Partition}:kafka:${Region}:${Account}:cluster/${ClusterName}/${UUID}
`arn:${cdk.Aws.PARTITION}:kafka:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:cluster/${clusterName}/*`,
`arn:${cdk.Aws.PARTITION}:kafka:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:group/${clusterName}/*/*`
],
actions: [
'kafka-cluster:Connect',
'kafka-cluster:DescribeCluster',
'kafka-cluster:AlterGroup',
'kafka-cluster:DescribeGroup',
'kafka-cluster:DeleteGroup'
]
}),
new iam.PolicyStatement({
sid: 'ProducerAPIs',
resources: [
`arn:${cdk.Aws.PARTITION}:kafka:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:topic/${clusterName}/*/*`
],
actions: ['kafka-cluster:*Topic*', 'kafka-cluster:WriteData']
}),
new iam.PolicyStatement({
sid: 'ConsumerAPIs',
resources: [
`arn:${cdk.Aws.PARTITION}:kafka:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:topic/${clusterName}/*/*`
],
actions: ['kafka-cluster:*Topic*', 'kafka-cluster:ReadData']
}),
]
});
this.addW12Suppression(mskPolicy, 'MSK actions do not support resource level permissions');
mskPolicy.attachToRole(role);
const cfnRole = role.node.defaultChild as iam.CfnRole;
return new iam.CfnInstanceProfile(this, 'InstanceProfile', {
roles: [cfnRole.ref]
});
}