in packages/constructs/L2/eks-constructs/lib/cluster.ts [313:666]
constructor(scope: Construct, id: string, props: MdaaEKSClusterProps) {
super(scope, id, MdaaEKSCluster.setProps(scope, props));
this.props = props;
this.clusterFargateProfileArn = `arn:${Stack.of(scope).partition}:eks:${Stack.of(scope).region}:${
Stack.of(scope).account
}:fargateprofile/${props.naming.resourceName(props.clusterName, 255)}/*`;
this.mdaaKubeCtlProvider = this.defineCompliantKubectlProvider();
props.adminRoles.forEach(adminRole => {
this.awsAuth.addMastersRole(adminRole);
});
const stackId = Fn.select(0, Fn.split('-', Fn.select(2, Fn.split('/', Stack.of(scope).stackId))));
const podLogGroupProps: LogGroupProps = {
encryptionKey: this.props.kmsKey,
logGroupName: `/aws/eks/${props.naming.resourceName(props.clusterName, 255)}/${stackId}/pods`,
retention: RetentionDays.INFINITE,
};
const podLogGroup = new LogGroup(this, 'pod-log-group', podLogGroupProps);
MdaaNagSuppressions.addCodeResourceSuppressions(
podLogGroup,
[
{
id: 'NIST.800.53.R5-CloudWatchLogGroupRetentionPeriod',
reason: 'LogGroup retention is set to RetentionDays.INFINITE.',
},
{
id: 'HIPAA.Security-CloudWatchLogGroupRetentionPeriod',
reason: 'LogGroup retention is set to RetentionDays.INFINITE.',
},
{
id: 'PCI.DSS.321-CloudWatchLogGroupRetentionPeriod',
reason: 'LogGroup retention is set to RetentionDays.INFINITE.',
},
],
true,
);
this.iamOidcIdentityProvider = new OpenIdConnectProvider(this, 'iam-oidc-identity-provider', {
url: this.clusterOpenIdConnectIssuerUrl,
clientIds: ['sts.amazonaws.com'],
});
this.podExecutionRolePolicy = new ManagedPolicy(this, 'systemPodExecutionRolePolicy', {
statements: [
new PolicyStatement({
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:DescribeLogStreams', 'logs:PutLogEvents'],
resources: [
`arn:${Stack.of(this).partition}:logs:${Stack.of(this).region}:${Stack.of(this).account}:log-group:${
podLogGroup.logGroupName
}*`,
`arn:${Stack.of(this).partition}:logs:${Stack.of(this).region}:${Stack.of(this).account}:log-group:${
podLogGroup.logGroupName
}:log-stream:*`,
],
effect: Effect.ALLOW,
}),
],
});
MdaaNagSuppressions.addCodeResourceSuppressions(
this.podExecutionRolePolicy,
[{ id: 'AwsSolutions-IAM5', reason: 'Log stream name not known at deployment time.' }],
true,
);
this.addFargateProfile('system', {
fargateProfileName: 'system',
selectors: [
{
namespace: 'default',
},
{
namespace: 'kube-system',
},
{
namespace: 'aws-observability',
},
],
});
const cdk8sApp = new cdk8s.App();
const efsStorageClassChart = new EfsStorageClassChart(cdk8sApp, 'efs-sc-chart');
this.efsStorageClassName = efsStorageClassChart.storageClassName;
this.addCdk8sChart('efs-sc-chart', efsStorageClassChart);
const awsObservabilityNamespace = this.addNamespace(
cdk8sApp,
'aws-observability-namespace',
'aws-observability',
props.securityGroup,
);
const awsObservabilityChart = this.addCdk8sChart(
'aws-observability-chart',
new AwsObservabilityChart(cdk8sApp, 'aws-observability-chart', {
logGroupName: podLogGroup.logGroupName,
region: Stack.of(this).region,
}),
);
awsObservabilityChart.node.addDependency(awsObservabilityNamespace);
MdaaNagSuppressions.addCodeResourceSuppressions(
this.role,
[{ id: 'AwsSolutions-IAM4', reason: 'AmazonEKSClusterPolicy is required for proper cluster function.' }],
true,
);
MdaaNagSuppressions.addCodeResourceSuppressions(
this.adminRole,
[
{
id: 'AwsSolutions-IAM5',
reason: 'EC2 resources not known at deployment time.',
appliesTo: [`Resource::*`],
},
{
id: 'AwsSolutions-IAM5',
reason: 'Permissions limited to specific cluster',
},
{
id: 'AwsSolutions-IAM5',
reason: 'Permissions limited to specific cluster',
},
{ id: 'NIST.800.53.R5-IAMNoInlinePolicy', reason: 'Permissions are specific to cluster.' },
{ id: 'HIPAA.Security-IAMNoInlinePolicy', reason: 'Permissions are specific to cluster.' },
{ id: 'PCI.DSS.321-IAMNoInlinePolicy', reason: 'Permissions are specific to cluster.' },
],
true,
);
if (this.kubectlLambdaRole) {
MdaaNagSuppressions.addCodeResourceSuppressions(
this.kubectlLambdaRole,
[
{
id: 'AwsSolutions-IAM4',
reason: 'AWSLambdaBasicExecutionRole, AWSLambdaVPCAccessExecutionRole are least privilege.',
},
{ id: 'AwsSolutions-IAM5', reason: 'S3 CDK Asset names not known at deployment time' },
{
id: 'NIST.800.53.R5-IAMNoInlinePolicy',
reason: 'Permissions are specific to custom resource requirements.',
},
{
id: 'HIPAA.Security-IAMNoInlinePolicy',
reason: 'Permissions are specific to custom resource requirements.',
},
{ id: 'PCI.DSS.321-IAMNoInlinePolicy', reason: 'Permissions are specific to custom resource requirements.' },
],
true,
);
}
const clusterResourceProvider = Stack.of(this).node.tryFindChild('@aws-cdk--aws-eks.ClusterResourceProvider');
if (clusterResourceProvider) {
MdaaNagSuppressions.addCodeResourceSuppressions(
clusterResourceProvider,
[
{
id: 'AwsSolutions-IAM4',
reason: 'AWSLambdaBasicExecutionRole, AWSLambdaVPCAccessExecutionRole are least privilege.',
},
{ id: 'AwsSolutions-IAM5', reason: 'Resource names not known at deployment time.' },
{ id: 'AwsSolutions-L1', reason: 'Function generated by EKS L2 construct.' },
{
id: 'NIST.800.53.R5-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'NIST.800.53.R5-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{ id: 'NIST.800.53.R5-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
{
id: 'NIST.800.53.R5-LambdaInsideVPC',
reason: 'Function is used as Cfn Custom Resource only during deployment time.',
},
{
id: 'HIPAA.Security-LambdaInsideVPC',
reason: 'Function is used as Cfn Custom Resource only during deployment time.',
},
{
id: 'PCI.DSS.321-LambdaInsideVPC',
reason: 'Function is used as Cfn Custom Resource only during deployment time.',
},
{
id: 'HIPAA.Security-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'PCI.DSS.321-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'HIPAA.Security-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{
id: 'PCI.DSS.321-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{ id: 'HIPAA.Security-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
{ id: 'PCI.DSS.321-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
{
id: 'HIPAA.Security-CloudWatchLogGroupEncrypted',
reason: 'Loggroup data is always encrypted in CloudWatch Logs',
},
{
id: 'PCI.DSS.321-CloudWatchLogGroupEncrypted',
reason: 'Loggroup data is always encrypted in CloudWatch Logs',
},
{
id: 'NIST.800.53.R5-CloudWatchLogGroupEncrypted',
reason: 'Loggroup data is always encrypted in CloudWatch Logs',
},
{ id: 'AwsSolutions-SF1', reason: 'Function is used as Cfn Custom Resource only during deployment time.' },
{ id: 'AwsSolutions-SF2', reason: 'Function is used as Cfn Custom Resource only during deployment time.' },
],
true,
);
}
const kubeCtlProvider = Stack.of(this).node.tryFindChild('@aws-cdk--aws-eks.KubectlProvider');
if (kubeCtlProvider) {
MdaaNagSuppressions.addCodeResourceSuppressions(
kubeCtlProvider,
[
{
id: 'AwsSolutions-IAM4',
reason: 'AWSLambdaBasicExecutionRole, AWSLambdaVPCAccessExecutionRole are least privilege.',
},
{ id: 'AwsSolutions-IAM5', reason: 'Resource names not known at deployment time.' },
{ id: 'AwsSolutions-L1', reason: 'Function generated by EKS L2 construct.' },
{
id: 'NIST.800.53.R5-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'NIST.800.53.R5-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{ id: 'NIST.800.53.R5-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
{
id: 'HIPAA.Security-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'PCI.DSS.321-LambdaConcurrency',
reason: 'Function is used as Cfn Custom Resource only during deployment time. Concurrency managed via Cfn.',
},
{
id: 'HIPAA.Security-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{
id: 'PCI.DSS.321-LambdaDLQ',
reason:
'Function is used as Cfn Custom Resource only during deployment time. Error handling managed via Cfn.',
},
{ id: 'HIPAA.Security-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
{ id: 'PCI.DSS.321-IAMNoInlinePolicy', reason: 'Policy statements are specific to custom resource.' },
],
true,
);
}
new MdaaParamAndOutput(
this,
{
...{
resourceType: 'cluster',
resourceId: props.clusterName,
name: 'arn',
value: this.clusterFargateProfileArn,
},
...props,
},
scope,
);
new MdaaParamAndOutput(
this,
{
...{
resourceType: 'cluster',
resourceId: props.clusterName,
name: 'name',
value: this.clusterName,
},
...props,
},
scope,
);
//Required to describe the cluster and configure kubectl
const eksStatment = new PolicyStatement({
actions: ['eks:DescribeCluster'],
effect: Effect.ALLOW,
resources: [this.clusterArn],
});
//Required to run SSM patching against instance
const ssmStatement = new PolicyStatement({
actions: [
'ssm:UpdateInstanceInformation',
'ssm:UpdateInstanceAssociationStatus',
'ssm:UpdateAssociationStatus',
'ssm:PutInventory',
'ssm:PutConfigurePackageResult',
'ssm:PutComplianceItems',
'ssm:ListInstanceAssociations',
'ssm:ListAssociations',
'ssm:GetManifest',
'ssm:GetDocument',
'ssm:GetDeployablePatchSnapshotForInstance',
'ssm:DescribeDocument',
'ssm:DescribeAssociation',
'ssmmessages:OpenDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:CreateControlChannel',
'ec2messages:SendReply',
'ec2messages:GetMessages',
'ec2messages:GetEndpoint',
'ec2messages:FailMessage',
'ec2messages:DeleteMessage',
'ec2messages:AcknowledgeMessage',
],
effect: Effect.ALLOW,
resources: ['*'],
});
const mgmtPolicy = new MdaaManagedPolicy(this, 'cluster-mgmt-policy', {
naming: props.naming,
managedPolicyName: 'cluster-mgmt',
statements: [eksStatment, ssmStatement, ...(props.mgmtInstance?.mgmtPolicyStatements || [])],
});
MdaaNagSuppressions.addCodeResourceSuppressions(
mgmtPolicy,
[
{
id: 'AwsSolutions-IAM5',
reason: 'Resource names not known at deployment time.',
},
],
true,
);
this.mgmtInstance = this.createMgmtInstance(mgmtPolicy);
}