constructor()

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);
  }