diff --git a/docs/builders/bedrock-builder.md b/docs/builders/bedrock-builder.md new file mode 100644 index 000000000..9dd36a098 --- /dev/null +++ b/docs/builders/bedrock-builder.md @@ -0,0 +1,66 @@ +# Bedrock Builder + +The `BedrockBuilder` allows you to get started with a builder class to configure required addons as you prepare a blueprint for setting up EKS cluster with access to Bedrock. + +The `BedrockBuilder` creates the following: + +- An EKS Cluster` with passed k8s version and cluster tags. +- A nodegroup to schedule Gen AI workloads with parameters passed. +- Sets up IRSA with access to Bedrock service. + +### Bedrock on EKS Cluster + +The below usage helps you with a demonstration to use `BedrockBuilder` to setup required addons as you prepare a blueprint for setting up Bedrock access to a new EKS cluster. + +```typescript +import { ApplicationTeam, BedrockBuilder, ClusterInfo } from "@aws-quickstart/eks-blueprints"; +import * as blueprints from "@aws-quickstart/eks-blueprints"; +import * as spi from '@aws-quickstart/eks-blueprints/dist/spi'; +import { Construct } from "constructs"; +import { loadYaml, readYamlDocument } from "@aws-quickstart/eks-blueprints/dist/utils"; +import { KubectlProvider, ManifestDeployment } from "@aws-quickstart/eks-blueprints/dist/addons/helm-addon/kubectl-provider"; + +export default class GenAIShowcase { + constructor(scope: Construct, id: string) { + const account = process.env.CDK_DEFAULT_ACCOUNT!; + const region = process.env.CDK_DEFAULT_REGION!; + const stackID = `${id}-blueprint`; + + const bedrockTeamProps: blueprints.teams.BedrockTeamProps = { + name: blueprints.utils.valueFromContext(scope, "bedrock.pattern.name", "showcase"), + namespace: blueprints.utils.valueFromContext(scope, "bedrock.pattern.namespace", "bedrock"), + createNamespace: true, + serviceAccountName: 'bedrock-service-account', + extensionFunction: extensionFunction + }; + + BedrockBuilder.builder() + .account(account) + .region(region) + .version('auto') + .addBedrockTeam(bedrockTeamProps) + .build(scope, stackID); + } +} + +function extensionFunction(team: ApplicationTeam, clusterInfo: ClusterInfo) { + const values: spi.Values = { + namespace: team.teamProps.namespace, + imageName: blueprints.utils.valueFromContext(clusterInfo.cluster, "bedrock.pattern.image.name", undefined), + imageTag: blueprints.utils.valueFromContext(clusterInfo.cluster, "bedrock.pattern.image.tag", undefined) + }; + + // Apply manifest + const doc = readYamlDocument(__dirname + '/deployment/showcase-deployment.ytpl'); + const manifest = doc.split("---").map((e: any) => loadYaml(e)); + + const manifestDeployment: ManifestDeployment = { + name: team.teamProps.name, + namespace: team.teamProps.namespace!, + manifest, + values + }; + const manifestConstruct = new KubectlProvider(clusterInfo).addManifest(manifestDeployment); + manifestConstruct.node.addDependency(team.serviceAccount); +} +``` \ No newline at end of file diff --git a/docs/builders/gpu-builder.md b/docs/builders/gpu-builder.md index 84e7b6bd5..4e6fa9a1e 100644 --- a/docs/builders/gpu-builder.md +++ b/docs/builders/gpu-builder.md @@ -4,7 +4,7 @@ The `GpuBuilder` allows you to get started with a builder class to configure wit The `GpuBuilder` creates the following: - An EKS Cluster` with passed k8s version and cluster tags. -- A nodegroup to schedule windows workloads with parameters passed. +- A nodegroup to schedule GPU workloads with parameters passed. ## Input Parameters @@ -13,7 +13,7 @@ The `GpuBuilder` creates the following: - `kubernetesVersion` : Required field, Kubernetes version to use for the cluster - `instanceClass`: Required field, Instance class to use for the cluster - `instanceSize`: Required field, Instance size to use for the cluster -- `nodeRole`: optional, Node IAM Role to be attached to Windows and Non-windows nodes. +- `nodeRole`: optional, Node IAM Role to be attached to nodes. - `gpuAmiType`: Required field, AMI Type for GPU Nodes. For example `AL2_X86_64_GPU`. - `desiredNodeSize`: Optional field, Desired number of nodes to use for the cluster - `minNodeSize`: Optional field, Minimum number of nodes to use for the cluster @@ -24,7 +24,7 @@ The `GpuBuilder` creates the following: ### Demonstration - Running GPUs on EKS Cluster -The below usage helps you with a demonstration to use `GpuBuilder` to configure a required setup as you prepare a blueprint for setting up windows nodes on a new EKS cluster. +The below usage helps you with a demonstration to use `GpuBuilder` to configure a required setup as you prepare a blueprint for setting up GPU nodes on a new EKS cluster. ```typescript import * as blueprints from "@aws-quickstart/eks-blueprints"; diff --git a/docs/builders/graviton-builder.md b/docs/builders/graviton-builder.md new file mode 100644 index 000000000..9e513c3eb --- /dev/null +++ b/docs/builders/graviton-builder.md @@ -0,0 +1,92 @@ +# GPU Builder + +The `GravitonBuilder` allows you to get started with a builder class to configure with required setup as you prepare a blueprint for setting up EKS cluster with Graviton worker nodes to run your ARM64 workloads. + +The `GravitonBuilder` creates the following: + +- An EKS Cluster` with passed k8s version and cluster tags. +- A nodegroup to schedule ARM64 workloads with parameters passed. + +## Input Parameters + +`Partial` parameters can be used as inputs to `GravitonBuilder`. Few parameters shown below: + +- `version` : Kubernetes version to use for the cluster +- `instanceTypes`: Instance Type to use for the cluster + +### Demonstration - Running Graviton Nodes on EKS Cluster + +The below usage helps you with a demonstration to use `GravitonBuilder` to configure a required setup as you prepare a blueprint for setting up Graviton nodes on a new EKS cluster. + +```typescript +import * as blueprints from "@aws-quickstart/eks-blueprints"; +import { GravitonBuilder } from "@aws-quickstart/eks-blueprints"; +import { CfnWorkspace } from "aws-cdk-lib/aws-aps"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import * as eks from "aws-cdk-lib/aws-eks"; +import { Construct } from "constructs"; + +export default class GravitonConstruct { + build(scope: Construct, id: string) { + const account = process.env.CDK_DEFAULT_ACCOUNT!; + const region = process.env.CDK_DEFAULT_REGION!; + const stackID = `${id}-blueprint`; + + const ampWorkspaceName = "graviton-amp-workspaces"; + const ampWorkspace: CfnWorkspace = + blueprints.getNamedResource(ampWorkspaceName); + + const options: Partial = { + version: eks.KubernetesVersion.of("1.27"), + instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE)], + desiredSize: 3, + minSize: 2, + maxSize: 5, + }; + + GravitonBuilder.builder(options) + .account(account) + .region(region) + .resourceProvider( + blueprints.GlobalResources.Vpc, + new blueprints.VpcProvider() + ) + .resourceProvider( + "efs-file-system", + new blueprints.CreateEfsFileSystemProvider({ + name: "efs-file-systems", + }) + ) + .resourceProvider( + ampWorkspaceName, + new blueprints.CreateAmpProvider( + ampWorkspaceName, + ampWorkspaceName + ) + ) + .addOns( + new blueprints.addons.IstioBaseAddOn(), + new blueprints.addons.IstioControlPlaneAddOn(), + new blueprints.addons.KubeStateMetricsAddOn(), + new blueprints.addons.MetricsServerAddOn(), + new blueprints.addons.PrometheusNodeExporterAddOn(), + new blueprints.addons.ExternalsSecretsAddOn(), + new blueprints.addons.SecretsStoreAddOn(), + new blueprints.addons.CalicoOperatorAddOn(), + new blueprints.addons.CertManagerAddOn(), + new blueprints.addons.AdotCollectorAddOn(), + new blueprints.addons.AmpAddOn({ + ampPrometheusEndpoint: ampWorkspace.attrPrometheusEndpoint + }), + new blueprints.addons.CloudWatchLogsAddon({ + logGroupPrefix: "/aws/eks/graviton-blueprint", + }), + new blueprints.addons.EfsCsiDriverAddOn(), + new blueprints.addons.FluxCDAddOn(), + new blueprints.addons.GrafanaOperatorAddon(), + new blueprints.addons.XrayAdotAddOn() + ) + .build(scope, stackID); + } +} +``` diff --git a/docs/builders/index.md b/docs/builders/index.md index 555c505af..7f32ea94b 100644 --- a/docs/builders/index.md +++ b/docs/builders/index.md @@ -6,5 +6,9 @@ The framework currently provides support for the following Builders: | Builder | Description | |-------------------|-----------------------------------------------------------------------------------| -| [`ObservabilityBuilder`](./observability-builder.md) | Allows you to get started with a builder class to configure required addons as you prepare a blueprint for setting up Observability on an existing EKS cluster or a new EKS cluster. +| [`BedrockBuilder`](./bedrock-builder.md) | The `BedrockBuilder` allows you to get started with a builder class to configure required addons as you prepare a blueprint for setting up an EKS cluster with access to Amazon Bedrock. +| [`GpuBuilder`](./gpu-builder.md) | The `GpuBuilder` allows you to get started with a builder class to configure with required setup as you prepare a blueprint for setting up EKS cluster with GPU Operator to run your GPU workloads. +| [`GravitonBuilder`](./graviton-builder.md) | The `GravitonBuilder` allows you to get started with a builder class to configure with required setup as you prepare a blueprint for setting up EKS cluster with Graviton worker nodes to run your ARM64 workloads. +| [`ObservabilityBuilder`](./observability-builder.md) | The `ObservabilityBuilder` allows you to get started with a builder class to configure required addons as you prepare a blueprint for setting up Observability on an existing EKS cluster or a new EKS cluster. +| [`WindowsBuilder`](./windows-builder.md) | The `WindowsBuilder` allows you to get started with a builder class to configure with required setup as you prepare a blueprint for setting up EKS cluster with windows to run your windows workloads. diff --git a/docs/extensibility.md b/docs/extensibility.md index 64767fc6a..b23cfd84b 100644 --- a/docs/extensibility.md +++ b/docs/extensibility.md @@ -1,14 +1,17 @@ # Extensibility -This guide provides an overview of extensibility options focusing on add-on extensions as the primary mechanism for the partners and customers. + +This guide provides an overview of extensibility options focusing on add-on extensions as the primary mechanism for the partners and customers. + ## Overview + Blueprints Framework is designed to be extensible. In the context of this guide, extensibility refers to the ability of customers and partners to both add new capabilities to the framework or platforms based on Blueprints as well as customize existing behavior, including the ability to modify or override existing behavior. The following abstractions can be leveraged to add new features to the framework: - [Add-on](./core-concepts.md#add-on). Customers and partners can implement new add-ons which could be leveraged exactly the same way as the core add-ons (supplied by the framework). -- [Resource Provider](./core-concepts.md#resource-provider). This construct allows customers to create resources that can be reused across multiple add-ons and/or teams. For example, IAM roles, VPC, hosted zone. +- [Resource Provider](./core-concepts.md#resource-provider). This construct allows customers to create resources that can be reused across multiple add-ons and/or teams. For example, IAM roles, VPC, hosted zone. - [Cluster Provider](./cluster-providers/index.md). This construct allows creation of custom code that provisions an EKS cluster with node groups. It can be leveraged to extend behavior such as control plane customization, custom settings for node groups. -- [Team](./teams/teams.md). This abstraction allows to create team templates for application and platform teams and set custom setting for network isolation, policies (network, security), software wiring (auto injection of proxies, team specific service mesh configuration) and other extensions pertinent to the teams. +- [Team](./teams/teams.md). This abstraction allows to create team templates for application and platform teams and set custom setting for network isolation, policies (network, security), software wiring (auto injection of proxies, team specific service mesh configuration) and other extensions pertinent to the teams. ## Add-on Extensions @@ -21,7 +24,7 @@ export declare interface ClusterAddOn { } ``` -**Note**: The add-on implementation can optionally supply the `id` attribute if the target add-on can be added to a blueprint more than once. +**Note**: The add-on implementation can optionally supply the `id` attribute if the target add-on can be added to a blueprint more than once. Implementation of the add-on is expected to be an exported class that implements the interface and supplies the implementation of the `deploy` method. In order for the add-on to receive the deployment contextual information about the provisioned cluster, region, resource providers and/or other add-ons, the `deploy` method takes the `ClusterInfo` parameter (see [types](https://github.com/aws-quickstart/cdk-eks-blueprints/blob/main/lib/spi/types.ts)), which represents a structure defined in the SPI (service provider interface) contracts. The API for the cluster info structure is stable and provides access to the provisioned EKS cluster, scheduled add-ons (that have not been installed yet but are part of the blueprint) or provisioned add-ons and other contexts. @@ -40,11 +43,11 @@ export declare interface ClusterPostDeploy { } ``` -This capability is leveraged for example in ArgoCD add-on to bootstrap workloads after all add-ons finished provisioning. Note, in this case unlike the standard `deploy` method implementation, the add-on also gets access to the provisioned teams. +This capability is leveraged for example in ArgoCD add-on to bootstrap workloads after all add-ons finished provisioning. Note, in this case unlike the standard `deploy` method implementation, the add-on also gets access to the provisioned teams. ### Helm Add-ons -Helm add-ons are the most common case that generally combines provisioning of a helm chart as well as supporting infrastructure such as wiring of proper IAM policies for the Kubernetes service account, provisioning or configuring other AWS resources (VPC, subnets, node groups). +Helm add-ons are the most common case that generally combines provisioning of a helm chart as well as supporting infrastructure such as wiring of proper IAM policies for the Kubernetes service account, provisioning or configuring other AWS resources (VPC, subnets, node groups). In order to provide consistency across all Helm add-ons supplied by the Blueprints framework all Helm add-ons are implemented as derivatives of the `HelmAddOn` base class and support properties based on `HelmAddOnUserProps`. See the [example extension section](#example-extension) below for more details. @@ -78,12 +81,13 @@ export class MyNonHelmAddOn implements blueprints.ClusterAddOn { } } ``` -**Note:** When leveraging this approach consider how customers can apply the add-on for fully private clusters. It may be reasonable to bundle the manifest with the add-on in the npm package. + +**Note:** When leveraging this approach consider how customers can apply the add-on for fully private clusters. It may be reasonable to bundle the manifest with the add-on in the npm package. ### Add-on Dependencies -Add-ons can depend on other add-ons and that dependency may be soft or hard. Hard dependency implies that add-on provisioning must fail if the dependency is not available. -For example, if an add-on requires access to AWS Secrets Manager for a secret containing a license key, credentials or other sensitive information, it can declare dependency on the CSI Secret Store Driver. +Add-ons can depend on other add-ons and that dependency may be soft or hard. Hard dependency implies that add-on provisioning must fail if the dependency is not available. +For example, if an add-on requires access to AWS Secrets Manager for a secret containing a license key, credentials or other sensitive information, it can declare dependency on the CSI Secret Store Driver. Dependency management for direct hard dependency are implemented using a decorator `@dependable`. @@ -145,11 +149,12 @@ const csiSecret: blueprints.addons.CsiSecretProps = { const secretProviderClass = new blueprints.addons.SecretProviderClass(clusterInfo, sa, "my-addon-license-secret-class", csiSecret); ``` -**Note:** you can also leverage `LookupSecretsManagerSecretByArn`, `LookupSsmSecretByAttrs` or a custom implementation of the secret provider interface `blueprints.addons.SecretProvider`. + +**Note:** you can also leverage `LookupSecretsManagerSecretByArn`, `LookupSsmSecretByAttrs` or a custom implementation of the secret provider interface `blueprints.addons.SecretProvider`. After the secret provider class is created, it should be mounted on any pod in the namespace to make the secret accessible. Mounting the secret volume also creates a regular Kubernetes `Secret` object based on the supplied description (`my-addon-license-secret`). This capability is controlled by the configuration of the Blueprints Secret Store add-on and is enabled by default. -Many Helm charts provide options to mount additional volumes and mounts to the provisioned product. For example, a Helm chart (ArgoCD, FluentBit) allows specifying `volumes` and `volumeMounts` as the helm chart values. Mounting the secret in such cases is simple and does not require an additional pod for secrets. +Many Helm charts provide options to mount additional volumes and mounts to the provisioned product. For example, a Helm chart (ArgoCD, FluentBit) allows specifying `volumes` and `volumeMounts` as the helm chart values. Mounting the secret in such cases is simple and does not require an additional pod for secrets. Here is an example of a secret volume and volume mount passed as values to a Helm chart: @@ -182,7 +187,7 @@ After the secret volume is mounted (on any pod), you will see that a Kubernetes ## Private Extensions -Extensions specific to a customer instance of Blueprints can be implemented inline with the blueprint in the same codebase. Such extensions are scoped to the customer base and cannot be reused. +Extensions specific to a customer instance of Blueprints can be implemented inline with the blueprint in the same codebase. Such extensions are scoped to the customer base and cannot be reused. Example of a private extension: ```typescript @@ -205,23 +210,24 @@ blueprints.EksBlueprint.builder() .addOns(new MyAddOn()) .build(app, 'my-extension-test-blueprint'); ``` + ## Public Extensions -The life-cycle of a public extension should be decoupled from the life-cycle of the [EKS Blueprints main repository](https://github.com/aws-quickstart/cdk-eks-blueprints). When decoupled, extensions can be released at any arbitrary cadence specific to the extension, enabling better agility when it comes to new features or bug fixes. +The life-cycle of a public extension should be decoupled from the life-cycle of the [EKS Blueprints main repository](https://github.com/aws-quickstart/cdk-eks-blueprints). When decoupled, extensions can be released at any arbitrary cadence specific to the extension, enabling better agility when it comes to new features or bug fixes. In order to enable this model the following workflow outline steps required to create and release a public extension: 1. Public extensions are created in a separate repository. Public GitHub repository is preferred as it aligns with the open-source spirit of the framework and enables external reviews/feedback. -2. Extensions are released and consumed as distinct public NPM packages. +2. Extensions are released and consumed as distinct public NPM packages. 3. Public Extensions are expected to have sufficient documentation to allow customers to consume them independently. Documentation can reside in GitHub or external resources referenced in the documentation bundled with the extension. -4. Public extensions are expected to be tested and validated against released Blueprints versions, e.g. with a CICD pipeline. Pipeline can be created with the [pipelines](./pipelines.md) support from the Blueprints framework or leveraging customer/partner specific tools. +4. Public extensions are expected to be tested and validated against released Blueprints versions, e.g. with a CICD pipeline. Pipeline can be created with the [pipelines](./pipelines.md) support from the Blueprints framework or leveraging customer/partner specific tools. ## Partner Extensions -Partner extensions (APN Partner) are expected to comply with the public extension workflow and additional items required to ensure proper validation and documentation support for a partner extension. +Partner extensions (APN Partner) are expected to comply with the public extension workflow and additional items required to ensure proper validation and documentation support for a partner extension. 1. Documentation PR should be created to the main [Blueprints Quickstart repository](https://github.com/aws-quickstart/cdk-eks-blueprints) to update the AddOns section. Example of add-on documentation can be found [here](https://aws-quickstart.github.io/cdk-eks-blueprints/addons/container-insights/) along with the list of other add-ons. -2. An example that shows a ready to use pattern leveraging the add-on should be submitted to the [Blueprints Patterns Repository](https://github.com/aws-samples/cdk-eks-blueprints-patterns). This step will enable AWS PSAs to validate the add-on as well as provide a ready to use pattern to the customers, that could be copied/cloned in their Blueprints implementation. +2. An example that shows a ready to use pattern leveraging the add-on should be submitted to the [Blueprints Patterns Repository](https://github.com/aws-samples/cdk-eks-blueprints-patterns). This step will enable AWS PSAs to validate the add-on as well as provide a ready to use pattern to the customers, that could be copied/cloned in their Blueprints implementation. ## Example Extension @@ -230,10 +236,39 @@ Partner extensions (APN Partner) are expected to comply with the public extensio 1. Pre-requisite configuration related to nodejs, npm, typescript. 2. Project template with support to build, test and run the extension. 3. Example blueprint (can be found in ./bin/main.ts) that references the add-on. -4. Example of configuring a Kubernetes service account with IRSA (IAM roles for service accounts) and required IAM policies. -5. Example of the helm chart provisioning. +4. Example of configuring a Kubernetes service account with IRSA (IAM roles for service accounts) and required IAM policies. +5. Example of the helm chart provisioning. 6. Example of passing secret values to the add-on (such as credentials and/or licenseKeys) by leveraging CSI Secret Store Driver. -7. Outlines support to build, package and publish the add-on in an NPM repository. +7. Outlines support to build, package and publish the add-on in an NPM repository. + +## Architecture Validation + +Architecture validation in the blueprints feature is to specify whether a particular addon supports architecture types such as `ARM`, `X86`. New addons should add the decorator `@supportALL` or `@supportX86` or `@supportARM` as shown below before the `class` to make sure the dynamic map is updated with addon name and supported architectures. + +```typescript +@supportsALL +export class AdotCollectorAddOn extends CoreAddOn { + + constructor(props?: AdotCollectorAddOnProps) { + super({ ...defaultProps, ...props }); + } + @dependable(CertManagerAddOn.name) +``` + +While creating solutions with blueprints, it is recommended to use the below method override to `addOns` method to validate a particular addon is supported for a particular architecure. + +```typescript + public addOns(...addOns: spi.ClusterAddOn[]): this { + addOns.forEach(a => validateSupportedArchitecture(a.constructor.name, ArchType.ARM)); + return super.addOns(...addOns); + } +``` + +In case of a particular addon not supporting an architecture type, following error is reportind during compile time: + +```output +Addon AckAddon is not supported on architecture ARM. +``` diff --git a/docs/teams/bedrock-team.md b/docs/teams/bedrock-team.md new file mode 100644 index 000000000..ef5a5c413 --- /dev/null +++ b/docs/teams/bedrock-team.md @@ -0,0 +1,26 @@ +# Bedrock Team + +The `BedrockTeam` extends the `ApplicationTeam` and allows the Bedrock team to manage the namespace where the generative AI workloads can be deployed. This team **MUST** be used in conjuction with [Bedrock Builder](../builders/bedrock-builder.md). + +The Bedrock Team allows you to create an IRSA to allow pods in namespace specified by the user to access Amazon Bedrock. + +## Usage + +```typescript +import * as cdk from 'aws-cdk-lib'; +import * as blueprints from '@aws-quickstart/eks-blueprints'; + +const app = new cdk.App(); + +const bedrockTeamProps: blueprints.BedrockTeamProps = { + namespace: 'bedrock', + createNamespace: true, + serviceAccountName: 'bedrock-service-account', +}; + + +const blueprint = blueprints.EksBlueprint.builder() + .version("auto") + .teams(new blueprints.BedrockTeam(bedrockTeamProps)) + .build(app, 'my-stack-name'); +``` diff --git a/lib/addons/ack/index.ts b/lib/addons/ack/index.ts index d623d6a77..e8c6d929d 100644 --- a/lib/addons/ack/index.ts +++ b/lib/addons/ack/index.ts @@ -3,7 +3,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; import "reflect-metadata"; -import { createNamespace, setPath } from "../../utils"; +import { createNamespace, setPath, supportsX86 } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; import { AckServiceName, serviceMappings } from './serviceMappings'; @@ -52,6 +52,7 @@ const defaultProps: AckAddOnProps = { * Main class to instantiate the Helm chart */ @Reflect.metadata("ordered", true) +@supportsX86 export class AckAddOn extends HelmAddOn { readonly options: AckAddOnProps; @@ -63,6 +64,7 @@ export class AckAddOn extends HelmAddOn { this.id = this.options.id; } + deploy(clusterInfo: ClusterInfo): Promise { const cluster = clusterInfo.cluster; diff --git a/lib/addons/adot/index.ts b/lib/addons/adot/index.ts index 3c6d33432..9943dafbd 100644 --- a/lib/addons/adot/index.ts +++ b/lib/addons/adot/index.ts @@ -1,7 +1,7 @@ import { KubernetesManifest } from "aws-cdk-lib/aws-eks"; import { Construct } from 'constructs'; import { ClusterInfo } from "../../spi"; -import { dependable, loadYaml, readYamlDocument } from "../../utils"; +import { dependable, loadYaml, readYamlDocument, supportsALL } from "../../utils"; import { CertManagerAddOn } from "../cert-manager"; import { CoreAddOn, CoreAddOnProps } from "../core-addon"; import { getAdotCollectorPolicyDocument } from "./iam-policy"; @@ -22,6 +22,7 @@ const defaultProps = { /** * Implementation of Adot Collector EKS add-on. */ +@supportsALL export class AdotCollectorAddOn extends CoreAddOn { constructor(props?: AdotCollectorAddOnProps) { diff --git a/lib/addons/amp/index.ts b/lib/addons/amp/index.ts index 335fde233..c473465f6 100644 --- a/lib/addons/amp/index.ts +++ b/lib/addons/amp/index.ts @@ -1,5 +1,5 @@ import { ClusterAddOn, ClusterInfo, Values } from "../../spi"; -import { dependable, loadYaml, readYamlDocument, changeTextBetweenTokens } from "../../utils"; +import { dependable, loadYaml, readYamlDocument, changeTextBetweenTokens, supportsALL } from "../../utils"; import { AdotCollectorAddOn } from "../adot"; import { Construct } from 'constructs'; import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider"; @@ -102,6 +102,7 @@ const defaultProps = { /** * Implementation of AMP add-on for EKS Blueprints. Installs ADOT Collector. */ +@supportsALL export class AmpAddOn implements ClusterAddOn { readonly ampAddOnProps: AmpAddOnProps; diff --git a/lib/addons/apache-airflow/index.ts b/lib/addons/apache-airflow/index.ts index eaa8656b1..ae317d613 100644 --- a/lib/addons/apache-airflow/index.ts +++ b/lib/addons/apache-airflow/index.ts @@ -13,7 +13,7 @@ import { EfsCsiDriverAddOn } from "../efs-csi-driver"; import { ClusterInfo } from '../../spi/types'; import { Values } from "../../spi"; -import { setPath, createNamespace, createServiceAccount } from "../../utils"; +import { setPath, createNamespace, createServiceAccount, supportsX86 } from "../../utils"; import { IFileSystem } from "aws-cdk-lib/aws-efs"; import merge from "ts-deepmerge"; @@ -87,6 +87,7 @@ const AIRFLOWPVC = 'efs-apache-airflow-pvc'; * This add-on is currently not supported. It will apply the latest falco helm chart but the latest AMI does not have stock driver supported and * driver build in the init fails atm. */ +@supportsX86 export class ApacheAirflowAddOn extends HelmAddOn { readonly options: AirflowAddOnProps; @@ -95,7 +96,7 @@ export class ApacheAirflowAddOn extends HelmAddOn { super({...defaultProps as any, ...props}); this.options = this.props as AirflowAddOnProps; } - + deploy(clusterInfo: ClusterInfo): Promise { const cluster = clusterInfo.cluster; const albAddOnCheck = clusterInfo.getScheduledAddOn(AwsLoadBalancerControllerAddOn.name); diff --git a/lib/addons/appmesh/index.ts b/lib/addons/appmesh/index.ts index ac72f700a..9ec8d0a62 100644 --- a/lib/addons/appmesh/index.ts +++ b/lib/addons/appmesh/index.ts @@ -5,6 +5,7 @@ import { assertEC2NodeGroup } from "../../cluster-providers"; import { ClusterInfo, Values } from "../../spi"; import { createNamespace } from "../../utils/namespace-utils"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; +import { supportsX86 } from "../../utils"; /** @@ -49,6 +50,7 @@ const defaultProps = { repository: "https://aws.github.io/eks-charts" }; +@supportsX86 export class AppMeshAddOn extends HelmAddOn { readonly options: AppMeshAddOnProps; diff --git a/lib/addons/argocd/index.ts b/lib/addons/argocd/index.ts index eb9591807..3fe5569b6 100644 --- a/lib/addons/argocd/index.ts +++ b/lib/addons/argocd/index.ts @@ -7,7 +7,7 @@ import * as dot from 'dot-object'; import merge from "ts-deepmerge"; import { SecretProviderClass } from '..'; import * as spi from "../../spi"; -import { createNamespace, getSecretValue, validateConstraints } from '../../utils'; +import { createNamespace, getSecretValue, supportsALL, validateConstraints } from '../../utils'; import { HelmAddOn, HelmAddOnUserProps } from '../helm-addon'; import { ArgoApplication } from './application'; import { createSecretRef } from './manifest-utils'; @@ -82,6 +82,7 @@ const defaultProps = { /** * Implementation of ArgoCD add-on and post deployment hook. */ +@supportsALL export class ArgoCDAddOn implements spi.ClusterAddOn, spi.ClusterPostDeploy { readonly options: ArgoCDAddOnProps; diff --git a/lib/addons/aws-batch-on-eks/index.ts b/lib/addons/aws-batch-on-eks/index.ts index 442b6bbcf..0499ea39c 100644 --- a/lib/addons/aws-batch-on-eks/index.ts +++ b/lib/addons/aws-batch-on-eks/index.ts @@ -4,9 +4,11 @@ import { Stack } from "aws-cdk-lib"; import { Cluster } from "aws-cdk-lib/aws-eks"; import { CfnServiceLinkedRole, IRole, Role } from "aws-cdk-lib/aws-iam"; import { Construct } from "constructs"; +import { supportsALL } from "../../utils"; const BATCH = 'aws-batch'; +@supportsALL export class AwsBatchAddOn implements ClusterAddOn { deploy(clusterInfo: ClusterInfo): Promise { assert(clusterInfo.cluster instanceof Cluster, "AwsBatchAddOn cannot be used with imported clusters"); diff --git a/lib/addons/aws-for-fluent-bit/index.ts b/lib/addons/aws-for-fluent-bit/index.ts index f1a4fc77c..098f4e613 100644 --- a/lib/addons/aws-for-fluent-bit/index.ts +++ b/lib/addons/aws-for-fluent-bit/index.ts @@ -4,6 +4,7 @@ import { Construct } from "constructs"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; import { ClusterInfo } from "../../spi/types"; import { createNamespace } from "../../utils/namespace-utils"; +import { supportsALL } from '../../utils'; /** * Configuration options for the FluentBit add-on. @@ -40,6 +41,7 @@ const defaultProps: AwsForFluentBitAddOnProps = { * For information on how to configure the `aws-for-fluent-bit` Helm chart to forward logs and metrics to AWS services like CloudWatch or Kinesis, please view the values.yaml spec provided by the chart. * https://github.com/aws/eks-charts/blob/master/stable/aws-for-fluent-bit/values.yaml */ +@supportsALL export class AwsForFluentBitAddOn extends HelmAddOn { readonly options: AwsForFluentBitAddOnProps; diff --git a/lib/addons/aws-loadbalancer-controller/index.ts b/lib/addons/aws-loadbalancer-controller/index.ts index 408eea81c..49991df38 100644 --- a/lib/addons/aws-loadbalancer-controller/index.ts +++ b/lib/addons/aws-loadbalancer-controller/index.ts @@ -5,6 +5,7 @@ import { ClusterInfo, Values } from "../../spi"; import { registries } from "../../utils/registry-utils"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; import { AwsLoadbalancerControllerIamPolicy } from "./iam-policy"; +import { supportsALL } from "../../utils"; /** * Configuration options for the add-on. @@ -76,6 +77,7 @@ function lookupImage(registry?: string, region?: string): Values { } @Reflect.metadata("ordered", true) +@supportsALL export class AwsLoadBalancerControllerAddOn extends HelmAddOn { readonly options: AwsLoadBalancerControllerProps; diff --git a/lib/addons/aws-node-termination-handler/index.ts b/lib/addons/aws-node-termination-handler/index.ts index dea200293..2f040661c 100644 --- a/lib/addons/aws-node-termination-handler/index.ts +++ b/lib/addons/aws-node-termination-handler/index.ts @@ -9,7 +9,7 @@ import { Duration } from 'aws-cdk-lib'; import { Construct } from "constructs"; import * as assert from "assert"; import { ClusterInfo } from '../../spi'; -import { tagAsg } from '../../utils'; +import { supportsX86, tagAsg } from '../../utils'; import { HelmAddOn, HelmAddOnUserProps } from '../helm-addon'; /** @@ -51,6 +51,7 @@ const defaultProps: AwsNodeTerminationHandlerProps = { mode: Mode.IMDS }; +@supportsX86 export class AwsNodeTerminationHandlerAddOn extends HelmAddOn { private options: AwsNodeTerminationHandlerProps; diff --git a/lib/addons/aws-privateca-issuer/index.ts b/lib/addons/aws-privateca-issuer/index.ts index e0f5f25c2..0bbed1ddc 100644 --- a/lib/addons/aws-privateca-issuer/index.ts +++ b/lib/addons/aws-privateca-issuer/index.ts @@ -4,7 +4,7 @@ import { ManagedPolicy } from "aws-cdk-lib/aws-iam"; import merge from "ts-deepmerge"; import { ServiceAccount } from 'aws-cdk-lib/aws-eks'; import { HelmAddOn, HelmAddOnUserProps, HelmAddOnProps } from "../helm-addon"; -import { dependable, setPath, createNamespace } from '../../utils'; +import { dependable, setPath, createNamespace, supportsX86 } from '../../utils'; import { ClusterInfo, Values } from "../../spi"; /** @@ -42,6 +42,7 @@ const defaultProps: HelmAddOnProps & AWSPrivateCAIssuerAddonProps = { /** * Main class to instantiate the Helm chart */ +@supportsX86 export class AWSPrivateCAIssuerAddon extends HelmAddOn { readonly options: AWSPrivateCAIssuerAddonProps; diff --git a/lib/addons/backstage/index.ts b/lib/addons/backstage/index.ts index 745e234ca..21d7dc3a7 100644 --- a/lib/addons/backstage/index.ts +++ b/lib/addons/backstage/index.ts @@ -1,6 +1,6 @@ import { Construct } from "constructs"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; -import { dependable, setPath } from "../../utils"; +import { dependable, setPath, supportsX86 } from "../../utils"; import { ClusterInfo, Values } from "../../spi"; import { ICertificate } from "aws-cdk-lib/aws-certificatemanager"; import * as rds from "aws-cdk-lib/aws-rds"; @@ -67,6 +67,7 @@ const defaultProps = { /** * Main class to instantiate the Helm chart */ +@supportsX86 export class BackstageAddOn extends HelmAddOn { readonly options: BackstageAddOnProps; @@ -76,8 +77,7 @@ export class BackstageAddOn extends HelmAddOn { this.options = this.props as BackstageAddOnProps; } - @dependable('AwsLoadBalancerControllerAddOn') - @dependable('ExternalsSecretsAddOn') + @dependable('AwsLoadBalancerControllerAddOn','ExternalsSecretsAddOn') deploy(clusterInfo: ClusterInfo): Promise { let values: Values = this.populateValues(clusterInfo, this.options); const chart = this.addHelmChart(clusterInfo, values); diff --git a/lib/addons/calico-operator/index.ts b/lib/addons/calico-operator/index.ts index 7dab55f52..1f373545f 100644 --- a/lib/addons/calico-operator/index.ts +++ b/lib/addons/calico-operator/index.ts @@ -1,6 +1,7 @@ import merge from "ts-deepmerge"; import { ClusterInfo } from "../../spi"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; +import { supportsALL } from "../../utils"; /** * Configuration options for the add-on. @@ -37,6 +38,7 @@ const defaultProps = { repository: "https://projectcalico.docs.tigera.io/charts" }; +@supportsALL export class CalicoOperatorAddOn extends HelmAddOn { private options: CalicoOperatorAddOnProps; diff --git a/lib/addons/calico/index.ts b/lib/addons/calico/index.ts index 474cf08e7..42edb89c6 100644 --- a/lib/addons/calico/index.ts +++ b/lib/addons/calico/index.ts @@ -2,6 +2,7 @@ import * as dot from 'dot-object'; import merge from "ts-deepmerge"; import { ClusterInfo } from "../../spi"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; +import { supportsX86 } from '../../utils'; /** * Configuration options for the add-on. @@ -42,6 +43,7 @@ const defaultProps = { /** * @deprecated use CalicoOperator add-on instead */ +@supportsX86 export class CalicoAddOn extends HelmAddOn { private options: CalicoAddOnProps; diff --git a/lib/addons/cert-manager/index.ts b/lib/addons/cert-manager/index.ts index e6b6b4603..fd69eae9f 100644 --- a/lib/addons/cert-manager/index.ts +++ b/lib/addons/cert-manager/index.ts @@ -2,7 +2,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace, dependable } from "../../utils"; +import { createNamespace, dependable, supportsALL } from "../../utils"; import { setPath } from '../../utils/object-utils'; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; import { AwsLoadBalancerControllerAddOn } from '../aws-loadbalancer-controller'; @@ -39,6 +39,7 @@ const defaultProps: HelmAddOnProps & CertManagerAddOnProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class CertManagerAddOn extends HelmAddOn { readonly options: CertManagerAddOnProps; diff --git a/lib/addons/cloudwatch-adot-addon/index.ts b/lib/addons/cloudwatch-adot-addon/index.ts index f80bd2edb..45dd1aafb 100644 --- a/lib/addons/cloudwatch-adot-addon/index.ts +++ b/lib/addons/cloudwatch-adot-addon/index.ts @@ -1,5 +1,5 @@ import { ClusterAddOn, ClusterInfo, Values } from "../../spi"; -import { dependable, loadYaml, readYamlDocument } from "../../utils"; +import { dependable, loadYaml, readYamlDocument, supportsALL } from "../../utils"; import { AdotCollectorAddOn } from "../adot"; import { Construct } from 'constructs'; import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider"; @@ -64,6 +64,7 @@ const defaultProps: CloudWatchAdotAddOnProps = { /** * Implementation of CloudWatch ADOT add-on for EKS Blueprints. Installs ADOT Collector. */ +@supportsALL export class CloudWatchAdotAddOn implements ClusterAddOn { readonly cloudWatchAddOnProps: CloudWatchAdotAddOnProps; diff --git a/lib/addons/cloudwatch-logs/index.ts b/lib/addons/cloudwatch-logs/index.ts index ec1c052b4..ceca9dc17 100644 --- a/lib/addons/cloudwatch-logs/index.ts +++ b/lib/addons/cloudwatch-logs/index.ts @@ -1,7 +1,7 @@ import { Construct } from "constructs"; import * as iam from "aws-cdk-lib/aws-iam"; import merge from "ts-deepmerge"; -import { conflictsWith, setPath } from "../../utils"; +import { conflictsWith, setPath, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; import { ClusterInfo, Values } from "../../spi/types"; import { createNamespace } from "../../utils/namespace-utils"; @@ -53,6 +53,7 @@ const defaultProps: CloudWatchLogsAddonProps = { * https://github.com/aws/eks-charts/tree/master/stable/aws-for-fluent-bit * */ +@supportsALL export class CloudWatchLogsAddon extends HelmAddOn { readonly options: CloudWatchLogsAddonProps; diff --git a/lib/addons/cluster-autoscaler/index.ts b/lib/addons/cluster-autoscaler/index.ts index b6cf62e39..f5d09e63b 100644 --- a/lib/addons/cluster-autoscaler/index.ts +++ b/lib/addons/cluster-autoscaler/index.ts @@ -4,7 +4,7 @@ import * as iam from "aws-cdk-lib/aws-iam"; import { Construct } from "constructs"; import { assertEC2NodeGroup } from "../../cluster-providers"; import { ClusterInfo } from "../../spi"; -import { conflictsWith, createNamespace, createServiceAccount, logger, setPath } from "../../utils"; +import { conflictsWith, createNamespace, createServiceAccount, logger, setPath, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; /** @@ -52,6 +52,7 @@ const versionMap: Map = new Map([ [KubernetesVersion.V1_18, "9.4.0"], ]); +@supportsALL export class ClusterAutoScalerAddOn extends HelmAddOn { private options: ClusterAutoScalerAddOnProps; diff --git a/lib/addons/container-insights/index.ts b/lib/addons/container-insights/index.ts index fd481da1c..3cd7ce10d 100644 --- a/lib/addons/container-insights/index.ts +++ b/lib/addons/container-insights/index.ts @@ -4,7 +4,7 @@ import merge from "ts-deepmerge"; import { ClusterInfo } from "../../spi"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; import { ValuesSchema } from "./values"; -import { conflictsWith, createNamespace } from "../../utils"; +import { conflictsWith, createNamespace, supportsALL } from "../../utils"; export interface ContainerInsightAddonProps extends Omit { values?: ValuesSchema @@ -19,6 +19,7 @@ const defaultProps = { repository: "https://aws-observability.github.io/aws-otel-helm-charts" }; +@supportsALL export class ContainerInsightsAddOn extends HelmAddOn { constructor(props?: ContainerInsightAddonProps) { diff --git a/lib/addons/coredns/index.ts b/lib/addons/coredns/index.ts index 7573f3a95..fdaf86110 100644 --- a/lib/addons/coredns/index.ts +++ b/lib/addons/coredns/index.ts @@ -1,3 +1,4 @@ +import {supportsALL } from "../../utils"; import { CoreAddOn, CoreAddOnProps } from "../core-addon"; /** @@ -15,10 +16,11 @@ const defaultProps = { /** * Implementation of CoreDns EKS add-on. */ +@supportsALL export class CoreDnsAddOn extends CoreAddOn { constructor(props?: CoreDnsAddOnProps) { super({ ...defaultProps, ...props }); } - + } diff --git a/lib/addons/ebs-csi-driver/index.ts b/lib/addons/ebs-csi-driver/index.ts index 8ad08de58..56acfeae8 100644 --- a/lib/addons/ebs-csi-driver/index.ts +++ b/lib/addons/ebs-csi-driver/index.ts @@ -3,6 +3,7 @@ import * as kms from "aws-cdk-lib/aws-kms"; import { ClusterInfo } from "../../spi"; import { CoreAddOn } from "../core-addon"; import { getEbsDriverPolicyDocument } from "./iam-policy"; +import { supportsALL } from "../../utils"; /** * Interface for EBS CSI Driver EKS add-on options @@ -30,6 +31,7 @@ const defaultProps = { /** * Implementation of EBS CSI Driver EKS add-on */ +@supportsALL export class EbsCsiDriverAddOn extends CoreAddOn { constructor(readonly options?: EbsCsiDriverAddOnProps) { diff --git a/lib/addons/efs-csi-driver/index.ts b/lib/addons/efs-csi-driver/index.ts index 8e993f700..4e75a6c57 100644 --- a/lib/addons/efs-csi-driver/index.ts +++ b/lib/addons/efs-csi-driver/index.ts @@ -1,10 +1,10 @@ import { Construct } from "constructs"; -import {ClusterInfo, Values} from "../../spi"; +import { ClusterInfo, Values} from "../../spi"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; import { getEfsDriverPolicyStatements } from "./iam-policy"; import { registries } from "../../utils/registry-utils"; import * as iam from "aws-cdk-lib/aws-iam"; -import {setPath} from "../../utils"; +import { setPath, supportsALL} from "../../utils"; import * as kms from "aws-cdk-lib/aws-kms"; @@ -45,6 +45,7 @@ const defaultProps: EfsCsiDriverProps = { replicaCount: 2 }; +@supportsALL export class EfsCsiDriverAddOn extends HelmAddOn { readonly options: EfsCsiDriverProps; diff --git a/lib/addons/emr-on-eks/index.ts b/lib/addons/emr-on-eks/index.ts index a62f4c3df..e4fc4f110 100644 --- a/lib/addons/emr-on-eks/index.ts +++ b/lib/addons/emr-on-eks/index.ts @@ -4,7 +4,9 @@ import { Stack } from "aws-cdk-lib"; import { Cluster } from "aws-cdk-lib/aws-eks"; import { CfnServiceLinkedRole, IRole, Role } from "aws-cdk-lib/aws-iam"; import { Construct } from "constructs"; +import { supportsALL } from "../../utils"; +@supportsALL export class EmrEksAddOn implements ClusterAddOn { deploy(clusterInfo: ClusterInfo): Promise { assert(clusterInfo.cluster instanceof Cluster, "EmrEksAddOn cannot be used with imported clusters as it requires changes to the cluster authentication."); diff --git a/lib/addons/external-dns/index.ts b/lib/addons/external-dns/index.ts index 64e5e4074..24c6d7ece 100644 --- a/lib/addons/external-dns/index.ts +++ b/lib/addons/external-dns/index.ts @@ -5,6 +5,7 @@ import { Construct } from "constructs"; import { ClusterInfo, Values } from '../../spi'; import { HelmAddOn, HelmAddOnUserProps } from '../helm-addon'; import merge from "ts-deepmerge"; +import { supportsALL } from '../../utils'; /** @@ -32,6 +33,7 @@ const defaultProps = { * Implementation of the External DNS service: https://github.com/kubernetes-sigs/external-dns/. * It is required to integrate with Route53 for external DNS resolution. */ +@supportsALL export class ExternalDnsAddOn extends HelmAddOn { private options: ExternalDnsProps; diff --git a/lib/addons/external-secrets/index.ts b/lib/addons/external-secrets/index.ts index f088adee2..98c2cced1 100644 --- a/lib/addons/external-secrets/index.ts +++ b/lib/addons/external-secrets/index.ts @@ -1,4 +1,4 @@ -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import * as iam from "aws-cdk-lib/aws-iam"; import merge from "ts-deepmerge"; import { Construct } from "constructs"; @@ -57,6 +57,7 @@ const defaultIamPolicy: iam.PolicyStatement = new iam.PolicyStatement({ * For information on how to configure the `external-secrets` Helm chart, please view the values.yaml spec provided by the chart. * https://github.com/external-secrets/external-secrets/blob/main/deploy/charts/external-secrets/values.yaml */ +@supportsALL export class ExternalsSecretsAddOn extends HelmAddOn { readonly options: ExternalsSecretsAddOnProps; diff --git a/lib/addons/falco/index.ts b/lib/addons/falco/index.ts index d2830b05b..e0657a164 100644 --- a/lib/addons/falco/index.ts +++ b/lib/addons/falco/index.ts @@ -2,7 +2,7 @@ import { HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; import { ClusterInfo } from '../../spi/types'; import { HelmAddOn } from '../helm-addon/index'; import { Construct } from "constructs"; -import { setPath } from "../../utils"; +import { setPath, supportsX86 } from "../../utils"; import { Values } from "../../spi"; /** @@ -54,6 +54,7 @@ export interface FalcoAddOnProps extends HelmAddOnUserProps { * This add-on is currently not supported. It will apply the latest falco helm chart but the latest AMI does not have stock driver supported and * driver build in the init fails atm. */ +@supportsX86 export class FalcoAddOn extends HelmAddOn { readonly options: FalcoAddOnProps; diff --git a/lib/addons/fluxcd/index.ts b/lib/addons/fluxcd/index.ts index 382a7820c..78d93fdde 100644 --- a/lib/addons/fluxcd/index.ts +++ b/lib/addons/fluxcd/index.ts @@ -3,7 +3,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import * as spi from "../../spi"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; import { FluxGitRepository } from "./gitrepository"; import { FluxKustomization } from "./kustomization"; @@ -116,6 +116,7 @@ const defaultKustomiationProps: FluxKustomizationProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class FluxCDAddOn extends HelmAddOn { readonly options: FluxCDAddOnProps; diff --git a/lib/addons/gpu-operator/index.ts b/lib/addons/gpu-operator/index.ts index e3b144d10..cf8f7ca95 100644 --- a/lib/addons/gpu-operator/index.ts +++ b/lib/addons/gpu-operator/index.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; import { ValuesSchema } from './values'; /** @@ -36,6 +36,7 @@ const defaultProps: HelmAddOnProps & GpuOperatorAddonProps = { * It validates all requisite software is installed before scheduling GPU workload * Using MIG (Multi Instance GPUs) allows you to virtually split your GPU into multiple units */ +@supportsALL export class GpuOperatorAddon extends HelmAddOn { readonly options: GpuOperatorAddonProps; diff --git a/lib/addons/grafana-operator/index.ts b/lib/addons/grafana-operator/index.ts index 7772addd8..6c2116450 100644 --- a/lib/addons/grafana-operator/index.ts +++ b/lib/addons/grafana-operator/index.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; /** * User provided options for the Helm Chart @@ -29,6 +29,7 @@ const defaultProps: HelmAddOnProps & GrafanaOperatorAddonProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class GrafanaOperatorAddon extends HelmAddOn { readonly options: GrafanaOperatorAddonProps; diff --git a/lib/addons/istio-base/index.ts b/lib/addons/istio-base/index.ts index 701aea121..c7641a244 100644 --- a/lib/addons/istio-base/index.ts +++ b/lib/addons/istio-base/index.ts @@ -4,6 +4,7 @@ import { ClusterInfo, Values } from "../../spi"; import { createNamespace } from "../../utils/namespace-utils"; import merge from "ts-deepmerge"; import { Duration } from "aws-cdk-lib"; +import { supportsALL } from "../../utils"; /** * Configuration options for the add-on. @@ -59,6 +60,7 @@ const defaultProps = { repository: "https://istio-release.storage.googleapis.com/charts" }; +@supportsALL export class IstioBaseAddOn extends HelmAddOn { readonly options: IstioBaseAddOnProps; diff --git a/lib/addons/istio-control-plane/index.ts b/lib/addons/istio-control-plane/index.ts index 39da59da0..33220e5e0 100644 --- a/lib/addons/istio-control-plane/index.ts +++ b/lib/addons/istio-control-plane/index.ts @@ -2,7 +2,7 @@ import { Construct } from "constructs"; import merge from "ts-deepmerge"; import { ClusterInfo } from "../../spi"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; -import { dependable } from '../../utils'; +import { dependable, supportsALL } from '../../utils'; import { ValuesSchema } from "./values"; export interface IstioControlPlaneAddOnProps extends HelmAddOnUserProps { @@ -18,6 +18,7 @@ const defaultProps = { repository: "https://istio-release.storage.googleapis.com/charts" }; +@supportsALL export class IstioControlPlaneAddOn extends HelmAddOn { constructor(props?: IstioControlPlaneAddOnProps) { diff --git a/lib/addons/jupyterhub/index.ts b/lib/addons/jupyterhub/index.ts index 45c3b6ad8..73eac3da1 100644 --- a/lib/addons/jupyterhub/index.ts +++ b/lib/addons/jupyterhub/index.ts @@ -1,7 +1,7 @@ import * as assert from "assert"; import { Construct } from "constructs"; import { ClusterInfo } from '../../spi'; -import { createNamespace, setPath } from '../../utils'; +import { createNamespace, setPath, supportsALL } from '../../utils'; import { AwsLoadBalancerControllerAddOn } from "../aws-loadbalancer-controller"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from '../helm-addon'; @@ -126,6 +126,7 @@ const defaultProps: HelmAddOnProps = { /** * Implementation of the JupyterHub add-on */ +@supportsALL export class JupyterHubAddOn extends HelmAddOn { readonly options: JupyterHubAddOnProps; diff --git a/lib/addons/karpenter/index.ts b/lib/addons/karpenter/index.ts index 34449ef6d..966449dac 100644 --- a/lib/addons/karpenter/index.ts +++ b/lib/addons/karpenter/index.ts @@ -2,7 +2,7 @@ import * as iam from 'aws-cdk-lib/aws-iam'; import { Construct } from "constructs"; import merge from 'ts-deepmerge'; import { ClusterInfo, Values, Taint } from '../../spi'; -import { conflictsWith, createNamespace, createServiceAccount, setPath, } from '../../utils'; +import { conflictsWith, createNamespace, createServiceAccount, setPath, supportsALL, } from '../../utils'; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from '../helm-addon'; import { KarpenterControllerPolicy } from './iam'; import { CfnOutput, Duration, Names } from 'aws-cdk-lib'; @@ -151,6 +151,7 @@ const defaultProps: HelmAddOnProps = { /** * Implementation of the Karpenter add-on */ +@supportsALL export class KarpenterAddOn extends HelmAddOn { readonly options: KarpenterAddOnProps; diff --git a/lib/addons/keda/index.ts b/lib/addons/keda/index.ts index 0992a8b6f..22a311ec6 100644 --- a/lib/addons/keda/index.ts +++ b/lib/addons/keda/index.ts @@ -3,7 +3,7 @@ import { ManagedPolicy } from "aws-cdk-lib/aws-iam"; import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace, setPath } from "../../utils"; +import { createNamespace, setPath, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; /** @@ -64,6 +64,7 @@ const defaultProps: HelmAddOnProps & KedaAddOnProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class KedaAddOn extends HelmAddOn { readonly options: KedaAddOnProps; diff --git a/lib/addons/knative-operator/index.ts b/lib/addons/knative-operator/index.ts index 0ccbd29b0..49afb9527 100644 --- a/lib/addons/knative-operator/index.ts +++ b/lib/addons/knative-operator/index.ts @@ -1,6 +1,6 @@ import { Construct } from 'constructs'; import { ClusterAddOn, ClusterInfo } from "../../spi"; -import {dependable, loadExternalYaml} from "../../utils"; +import { dependable, loadExternalYaml, supportsALL} from "../../utils"; import { HelmAddOnUserProps } from '../helm-addon'; import { KubectlProvider } from "../helm-addon/kubectl-provider"; @@ -36,6 +36,7 @@ const defaultProps = { /** * Implementation of KNative add-on for EKS Blueprints. Installs KNative to the Cluster. */ +@supportsALL export class KNativeOperator implements ClusterAddOn { readonly knativeAddOnProps: KnativeOperatorProps; diff --git a/lib/addons/kube-proxy/index.ts b/lib/addons/kube-proxy/index.ts index e57a5e219..8245d7181 100644 --- a/lib/addons/kube-proxy/index.ts +++ b/lib/addons/kube-proxy/index.ts @@ -1,5 +1,6 @@ import { KubernetesVersion } from "aws-cdk-lib/aws-eks"; import { CoreAddOn, CoreAddOnProps } from "../core-addon"; +import { supportsALL } from "../../utils"; const versionMap: Map = new Map([ [KubernetesVersion.V1_27, "v1.27.1-eksbuild.1"], @@ -23,6 +24,7 @@ const defaultProps = { /** * Implementation of KubeProxy EKS add-on. */ +@supportsALL export class KubeProxyAddOn extends CoreAddOn { constructor(version?: string, props?: kubeProxyAddOnProps) { diff --git a/lib/addons/kube-state-metrics/index.ts b/lib/addons/kube-state-metrics/index.ts index 0239c12b4..4e4933cc1 100644 --- a/lib/addons/kube-state-metrics/index.ts +++ b/lib/addons/kube-state-metrics/index.ts @@ -2,7 +2,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; /** * User provided option for the Helm Chart @@ -32,6 +32,7 @@ const defaultProps: HelmAddOnProps & KubeStateMetricsAddOnProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class KubeStateMetricsAddOn extends HelmAddOn { readonly options: KubeStateMetricsAddOnProps; diff --git a/lib/addons/kubevious/index.ts b/lib/addons/kubevious/index.ts index bd386f216..d5f86d75c 100644 --- a/lib/addons/kubevious/index.ts +++ b/lib/addons/kubevious/index.ts @@ -1,7 +1,7 @@ import { Construct } from "constructs"; import { HelmAddOn, HelmAddOnUserProps, HelmAddOnProps } from "../helm-addon"; import { ClusterInfo, Values } from "../../spi"; -import { setPath } from "../../utils"; +import { setPath, supportsX86 } from "../../utils"; /** @@ -41,6 +41,7 @@ const defaultProps: HelmAddOnProps & KubeviousAddOnProps = { /** * Main class to instantiate the Helm chart */ +@supportsX86 export class KubeviousAddOn extends HelmAddOn { readonly options: KubeviousAddOnProps; diff --git a/lib/addons/metrics-server/index.ts b/lib/addons/metrics-server/index.ts index d789180de..c569cfccd 100644 --- a/lib/addons/metrics-server/index.ts +++ b/lib/addons/metrics-server/index.ts @@ -2,7 +2,7 @@ import { Construct } from 'constructs'; import merge from 'ts-deepmerge'; import { ClusterInfo, Values } from '../../spi'; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from '../helm-addon'; -import { createNamespace } from '../../utils'; +import { createNamespace, supportsALL } from '../../utils'; /** * Configuration options for the add-on. @@ -28,6 +28,7 @@ const defaultProps: HelmAddOnProps & MetricsServerAddOnProps = { createNamespace: false, }; +@supportsALL export class MetricsServerAddOn extends HelmAddOn { readonly options: MetricsServerAddOnProps; diff --git a/lib/addons/nested-stack/index.ts b/lib/addons/nested-stack/index.ts index 36d86942c..e3ac2819b 100644 --- a/lib/addons/nested-stack/index.ts +++ b/lib/addons/nested-stack/index.ts @@ -1,6 +1,7 @@ import { NestedStackProps } from "aws-cdk-lib"; import { Construct } from "constructs"; import { ClusterAddOn, ClusterInfo, NestedStackBuilder } from "../../spi"; +import { supportsALL } from "../../utils"; /** * Properties for the nested stack add-on. @@ -22,6 +23,7 @@ export class NestedStackAddOnProps { nestedStackProps?: NestedStackProps; } +@supportsALL export class NestedStackAddOn implements ClusterAddOn { readonly id? : string; diff --git a/lib/addons/nginx/index.ts b/lib/addons/nginx/index.ts index c7ea47127..d13438c92 100644 --- a/lib/addons/nginx/index.ts +++ b/lib/addons/nginx/index.ts @@ -3,7 +3,7 @@ import { Construct } from "constructs"; import merge from "ts-deepmerge"; import { AwsLoadBalancerControllerAddOn } from ".."; import { ClusterInfo, Values } from "../../spi"; -import { dependable } from "../../utils"; +import { dependable, supportsALL } from "../../utils"; import { setPath } from "../../utils/object-utils"; import * as dot from 'dot-object'; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; @@ -70,6 +70,7 @@ const defaultProps: NginxAddOnProps = { namespace: 'kube-system' }; +@supportsALL export class NginxAddOn extends HelmAddOn { readonly options: NginxAddOnProps; diff --git a/lib/addons/opa-gatekeeper/index.ts b/lib/addons/opa-gatekeeper/index.ts index 7f88ef8e5..227a239ea 100644 --- a/lib/addons/opa-gatekeeper/index.ts +++ b/lib/addons/opa-gatekeeper/index.ts @@ -1,4 +1,5 @@ import { ClusterInfo, ClusterPostDeploy, Team } from "../../spi"; +import { supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; /** @@ -22,6 +23,7 @@ const defaultProps: HelmAddOnProps = { version: '3.13.0' }; +@supportsALL export class OpaGatekeeperAddOn extends HelmAddOn implements ClusterPostDeploy { private options: OpaGatekeeperAddOnProps; diff --git a/lib/addons/prometheus-node-exporter/index.ts b/lib/addons/prometheus-node-exporter/index.ts index 9b132a795..c086dd87a 100644 --- a/lib/addons/prometheus-node-exporter/index.ts +++ b/lib/addons/prometheus-node-exporter/index.ts @@ -2,7 +2,7 @@ import { Construct } from 'constructs'; import merge from "ts-deepmerge"; import { ClusterInfo, Values } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnProps, HelmAddOnUserProps } from "../helm-addon"; /** * User provided option for the Helm Chart @@ -32,6 +32,7 @@ const defaultProps: HelmAddOnProps & PrometheusNodeExporterAddOnProps = { /** * Main class to instantiate the Helm chart */ +@supportsALL export class PrometheusNodeExporterAddOn extends HelmAddOn { readonly options: PrometheusNodeExporterAddOnProps; diff --git a/lib/addons/secrets-store/index.ts b/lib/addons/secrets-store/index.ts index f05e89b66..3a9e91081 100644 --- a/lib/addons/secrets-store/index.ts +++ b/lib/addons/secrets-store/index.ts @@ -2,7 +2,7 @@ import { Construct } from "constructs"; import { ClusterAddOn, ClusterInfo } from '../../spi'; import { HelmAddOnUserProps } from '../helm-addon'; import { CsiDriverProviderAws } from './csi-driver-provider-aws'; -import { cloneDeep } from "../../utils"; +import { cloneDeep, supportsALL } from "../../utils"; /** * Configuration options for Secrets Store AddOn @@ -53,6 +53,7 @@ const defaultProps: SecretsStoreAddOnProps = { syncSecrets: true, }; +@supportsALL export class SecretsStoreAddOn implements ClusterAddOn { private options: SecretsStoreAddOnProps; diff --git a/lib/addons/ssm-agent/index.ts b/lib/addons/ssm-agent/index.ts index 8524cb8e3..d39db7425 100644 --- a/lib/addons/ssm-agent/index.ts +++ b/lib/addons/ssm-agent/index.ts @@ -2,7 +2,9 @@ import { KubernetesManifest } from "aws-cdk-lib/aws-eks"; import { ManagedPolicy } from "aws-cdk-lib/aws-iam"; import { assertEC2NodeGroup } from "../../cluster-providers"; import { ClusterAddOn, ClusterInfo } from "../../spi"; +import { supportsX86 } from "../../utils"; +@supportsX86 export class SSMAgentAddOn implements ClusterAddOn { deploy(clusterInfo: ClusterInfo): void { const cluster = clusterInfo.cluster; diff --git a/lib/addons/upbound-universal-crossplane/index.ts b/lib/addons/upbound-universal-crossplane/index.ts index e3ab51a9c..0afd8485b 100644 --- a/lib/addons/upbound-universal-crossplane/index.ts +++ b/lib/addons/upbound-universal-crossplane/index.ts @@ -1,4 +1,5 @@ import { CoreAddOn } from "../core-addon"; +import { supportsX86 } from "../../utils"; /** * Interface for Upbound Universal Crossplane EKS add-on options @@ -19,8 +20,9 @@ const defaultProps = { }; /** - * Implementation of EBS CSI Driver EKS add-on + * Implementation of Upbound Crossplane EKS add-on */ +@supportsX86 export class UpboundUniversalCrossplaneAddOn extends CoreAddOn { constructor(readonly options?: UpboundUniversalCrossplaneAddOnProps) { diff --git a/lib/addons/velero/index.ts b/lib/addons/velero/index.ts index f5a6d38c8..793684628 100644 --- a/lib/addons/velero/index.ts +++ b/lib/addons/velero/index.ts @@ -4,7 +4,7 @@ import * as s3 from "aws-cdk-lib/aws-s3"; import { Construct } from "constructs"; import merge from "ts-deepmerge"; import { ClusterInfo } from "../../spi"; -import { createNamespace } from "../../utils"; +import { createNamespace, supportsALL } from "../../utils"; import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon"; /** @@ -56,6 +56,7 @@ const defaultProps = { }, }; +@supportsALL export class VeleroAddOn extends HelmAddOn { private options: Required; diff --git a/lib/addons/vpc-cni/index.ts b/lib/addons/vpc-cni/index.ts index 71a9a5544..559994f71 100644 --- a/lib/addons/vpc-cni/index.ts +++ b/lib/addons/vpc-cni/index.ts @@ -3,7 +3,7 @@ import * as eks from "aws-cdk-lib/aws-eks"; import * as iam from "aws-cdk-lib/aws-iam"; import { Construct } from 'constructs'; import { ClusterInfo, Values } from "../../spi"; -import { loadYaml, readYamlDocument, ReplaceServiceAccount } from "../../utils"; +import { loadYaml, readYamlDocument, ReplaceServiceAccount, supportsALL } from "../../utils"; import { CoreAddOn, CoreAddOnProps } from "../core-addon"; import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider"; @@ -302,6 +302,7 @@ const defaultProps: CoreAddOnProps = { /** * Implementation of VpcCni EKS add-on with Advanced Configurations. */ +@supportsALL export class VpcCniAddOn extends CoreAddOn { readonly vpcCniAddOnProps: VpcCniAddOnProps; diff --git a/lib/addons/xray-adot-addon/index.ts b/lib/addons/xray-adot-addon/index.ts index ad34e0b2b..d982718f2 100644 --- a/lib/addons/xray-adot-addon/index.ts +++ b/lib/addons/xray-adot-addon/index.ts @@ -1,5 +1,5 @@ import { ClusterAddOn, ClusterInfo, Values } from "../../spi"; -import { dependable, loadYaml, readYamlDocument } from "../../utils"; +import { dependable, loadYaml, readYamlDocument, supportsALL } from "../../utils"; import { AdotCollectorAddOn } from "../adot"; import { Construct } from 'constructs'; import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider"; @@ -50,6 +50,7 @@ const defaultProps = { /** * Implementation of XRAY ADOT add-on for EKS Blueprints. Installs ADOT Collector. */ +@supportsALL export class XrayAdotAddOn implements ClusterAddOn { readonly xrayAddOnProps: XrayAdotAddOnProps; diff --git a/lib/addons/xray/index.ts b/lib/addons/xray/index.ts index e4a102782..7134e0a93 100644 --- a/lib/addons/xray/index.ts +++ b/lib/addons/xray/index.ts @@ -2,12 +2,13 @@ import { KubernetesManifest } from "aws-cdk-lib/aws-eks"; import { ManagedPolicy } from "aws-cdk-lib/aws-iam"; import { assertEC2NodeGroup } from "../../cluster-providers"; import { ClusterAddOn, ClusterInfo } from "../../spi"; -import { loadYaml, readYamlDocument } from "../../utils"; +import { loadYaml, readYamlDocument, supportsX86 } from "../../utils"; /** * Implementation of AWS X-Ray add-on for EKS Blueprints. Installs xray daemonset and exposes * an internal ClusterIP service for tracing on port 2000 (UDP). */ +@supportsX86 export class XrayAddOn implements ClusterAddOn { deploy(clusterInfo: ClusterInfo): void { diff --git a/lib/builders/bedrock-builder.ts b/lib/builders/bedrock-builder.ts new file mode 100644 index 000000000..e79a89472 --- /dev/null +++ b/lib/builders/bedrock-builder.ts @@ -0,0 +1,61 @@ +import { BlueprintBuilder } from '../stacks'; +import * as utils from "../utils"; +import * as addons from '../addons'; +import * as teams from '../teams'; +import * as spi from '../spi'; +import { NestedStack, NestedStackProps } from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import { cloneDeep } from '../utils'; + +export class BedrockBuilder extends BlueprintBuilder { + + /* This method helps you add a bedrock team to the blueprint. + */ + public addBedrockTeam(props: teams.BedrockTeamProps) : this { + return this.teams(new teams.BedrockTeam(cloneDeep(props))); + } + + /** + * This method helps you prepare a blueprint for setting up EKS cluster with + * usage tracking addon + */ + public static builder(): BedrockBuilder { + const builder = new BedrockBuilder(); + + builder.addOns( + new addons.NestedStackAddOn({ + id: "usage-tracking-addon", + builder: UsageTrackingAddOn.builder(), + }), + new addons.AwsLoadBalancerControllerAddOn(), + new addons.CoreDnsAddOn(), + new addons.CertManagerAddOn(), + new addons.KubeStateMetricsAddOn(), + new addons.KubeProxyAddOn(), + new addons.MetricsServerAddOn(), + new addons.SSMAgentAddOn(), + new addons.VpcCniAddOn(), + ); + return builder; + } +} + +/** + * Nested stack that is used as tracker + */ +class UsageTrackingAddOn extends NestedStack { + + static readonly USAGE_ID = "qs-1uijcfop9"; + + public static builder(): spi.NestedStackBuilder { + return { + build(scope: Construct, id: string, props: NestedStackProps) { + return new UsageTrackingAddOn(scope, id, props); + } + }; + } + + constructor(scope: Construct, id: string, props: NestedStackProps) { + super(scope, id, utils.withUsageTracking(UsageTrackingAddOn.USAGE_ID, props)); + } +} \ No newline at end of file diff --git a/lib/builders/gpu-builder.ts b/lib/builders/gpu-builder.ts index 0f76ad85f..6ceb7ecfa 100644 --- a/lib/builders/gpu-builder.ts +++ b/lib/builders/gpu-builder.ts @@ -81,7 +81,8 @@ const defaultOptions: GpuOptions = { "Type": "Managed-linux-Gpu-Node-Group", "LaunchTemplate": "Linux-Launch-Template", } - }; +}; + export class GpuBuilder extends BlueprintBuilder { /** * This method helps you prepare a blueprint for setting up observability diff --git a/lib/builders/graviton-builder.ts b/lib/builders/graviton-builder.ts new file mode 100644 index 000000000..cf48e4fcc --- /dev/null +++ b/lib/builders/graviton-builder.ts @@ -0,0 +1,82 @@ +import { BlueprintBuilder } from '../stacks'; +import * as utils from "../utils"; +import * as addons from '../addons'; +import * as spi from '../spi'; +import { MngClusterProvider, MngClusterProviderProps } from '../cluster-providers'; +import { NestedStack, NestedStackProps } from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as eks from "aws-cdk-lib/aws-eks"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import { validateSupportedArchitecture, ArchType } from "../utils"; +import merge from 'ts-deepmerge'; + +/** + * Default props to be used when creating the Graviton nodes + * for EKS cluster + */ +const defaultOptions: Partial = { + version: eks.KubernetesVersion.of("1.27"), + instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE)], + amiType: eks.NodegroupAmiType.AL2_ARM_64, + desiredSize: 3, + minSize: 2, + maxSize: 5 +}; + +/** + * This builder class helps you prepare a blueprint for setting up + * Graviton nodes with EKS cluster. The `GravitonBuilder` creates the following: + * 1. An EKS Cluster` with passed k8s version. + * 2. A managed graviton nodegroup for ARM64 software. + * 3. Validates each addon is supported for the given architecture. + * + * @example + * ```typescript + * import { GravitonBuilder } + */ + +export class GravitonBuilder extends BlueprintBuilder { + + public addOns(...addOns: spi.ClusterAddOn[]): this { + addOns.forEach(a => validateSupportedArchitecture(a.constructor.name, ArchType.ARM)); + return super.addOns(...addOns); + } + + public static builder(options: Partial): GravitonBuilder { + const builder = new GravitonBuilder(); + const mergedOptions = merge(defaultOptions, options); + + builder + .clusterProvider(new MngClusterProvider(mergedOptions)) + .addOns( + new addons.NestedStackAddOn({ + id: "usage-tracking-addon", + builder: UsageTrackingAddOn.builder(), + }), + new addons.AwsLoadBalancerControllerAddOn(), + new addons.KubeProxyAddOn("v1.27.1-eksbuild.1"), + new addons.VpcCniAddOn(), + ); + return builder; + } +} + +/** + * Nested stack that is used as tracker for Graviton Accelerator + */ +export class UsageTrackingAddOn extends NestedStack { + + static readonly USAGE_ID = "qs-1ub15dn1f"; + + public static builder(): spi.NestedStackBuilder { + return { + build(scope: Construct, id: string, props: NestedStackProps) { + return new UsageTrackingAddOn(scope, id, props); + } + }; + } + + constructor(scope: Construct, id: string, props: NestedStackProps) { + super(scope, id, utils.withUsageTracking(UsageTrackingAddOn.USAGE_ID, props)); + } +} \ No newline at end of file diff --git a/lib/builders/index.ts b/lib/builders/index.ts index d63603b89..eb8a1e4e3 100644 --- a/lib/builders/index.ts +++ b/lib/builders/index.ts @@ -1,3 +1,5 @@ +export * from "./bedrock-builder"; +export * from "./graviton-builder"; +export * from "./gpu-builder"; export * from "./observability-builder"; export * from "./windows-builder"; -export * from "./gpu-builder"; diff --git a/lib/teams/bedrock-team/bedrock-team.ts b/lib/teams/bedrock-team/bedrock-team.ts new file mode 100644 index 000000000..315a9060b --- /dev/null +++ b/lib/teams/bedrock-team/bedrock-team.ts @@ -0,0 +1,51 @@ +import { ClusterInfo } from "../../spi"; +import { ApplicationTeam, TeamProps } from "../team"; +import { getBedrockPolicyDocument } from "./iam-policy"; +import * as iam from "aws-cdk-lib/aws-iam"; + +/** + * Interface to define a GenAI on EKS team + */ +export interface BedrockTeamProps extends TeamProps { + /** + * Name of the service account namespace. + */ + namespace?: string; + + /** + * Create Namespace with the provided one. + */ + createNamespace?: boolean + + /** + * Name of the service account for Bedrock. + */ + serviceAccountName?: string; +} + +/* + *This class define the Team that can be used with `GenAIBuilder` + *Sets IRSA for access to bedrock with required IAM policy along with creating a namespace. +*/ + +export class BedrockTeam extends ApplicationTeam { + + private bedrockTeam: BedrockTeamProps; + /** + * @public + * @param {BedrockTeamProps} props the Bedrock team definition {@link BedrockTeamProps} + */ + constructor(props: BedrockTeamProps) { + super(props); + this.bedrockTeam = props; + } + + protected setupServiceAccount(clusterInfo: ClusterInfo) { + + super.setupServiceAccount(clusterInfo); + // Apply IAM policy for Bedrock to the service account. + getBedrockPolicyDocument().forEach((statement) => { + this.serviceAccount.addToPrincipalPolicy(iam.PolicyStatement.fromJson(statement)); + }); + } +} diff --git a/lib/teams/bedrock-team/iam-policy.ts b/lib/teams/bedrock-team/iam-policy.ts new file mode 100644 index 000000000..9c65a0396 --- /dev/null +++ b/lib/teams/bedrock-team/iam-policy.ts @@ -0,0 +1,18 @@ +interface Statement { + Effect: string; + Action: string | string[]; + Resource: string | string[]; +} + +export function getBedrockPolicyDocument() : Statement[] { + const result: Statement[] = [ + { + "Effect": "Allow", + "Action": [ + "bedrock:*", + ], + "Resource": "*" + } + ]; + return result; +} diff --git a/lib/teams/emr-on-eks-team.ts b/lib/teams/emr-on-eks-team.ts index ef11f00cc..65419db62 100644 --- a/lib/teams/emr-on-eks-team.ts +++ b/lib/teams/emr-on-eks-team.ts @@ -54,7 +54,7 @@ export interface EmrEksTeamProps extends TeamProps { /** * Tags to apply to EMR on EKS Virtual Cluster */ - virtualClusterTags?: CfnTag[]; + virtualClusterTags?: CfnTag[]; } /* diff --git a/lib/teams/index.ts b/lib/teams/index.ts index 01860e96d..0305ff1ce 100644 --- a/lib/teams/index.ts +++ b/lib/teams/index.ts @@ -1,3 +1,4 @@ export * from './team'; +export * from './bedrock-team/bedrock-team'; export * from './emr-on-eks-team'; export * from './aws-batch/aws-batch-on-eks-team'; \ No newline at end of file diff --git a/lib/teams/team.ts b/lib/teams/team.ts index ff08efb22..284cd8581 100644 --- a/lib/teams/team.ts +++ b/lib/teams/team.ts @@ -78,7 +78,13 @@ export class TeamProps { /** * Optional, directory where a team's manifests are stored */ - readonly teamManifestDir?: string; + readonly teamManifestDir?: string; + + /** + * Optional, Use this function to add infrastructure or workloads + * deploymentto the team + */ + extensionFunction? (team: ApplicationTeam, clusterInfo: ClusterInfo): void; } export class ApplicationTeam implements Team { @@ -104,7 +110,8 @@ export class ApplicationTeam implements Team { serviceAccountPolicies: teamProps.serviceAccountPolicies, userRoleArn: teamProps.userRoleArn, teamSecrets: teamProps.teamSecrets, - teamManifestDir: teamProps.teamManifestDir + teamManifestDir: teamProps.teamManifestDir, + extensionFunction: teamProps.extensionFunction }; } @@ -113,6 +120,9 @@ export class ApplicationTeam implements Team { this.setupNamespace(clusterInfo); this.setupServiceAccount(clusterInfo); this.setupSecrets(clusterInfo); + if (this.teamProps.extensionFunction) { + this.teamProps.extensionFunction(this, clusterInfo); + } } protected defaultSetupAccess(clusterInfo: ClusterInfo) { diff --git a/lib/utils/addon-utils.ts b/lib/utils/addon-utils.ts index 7bbd2a0f0..b67db5ad3 100644 --- a/lib/utils/addon-utils.ts +++ b/lib/utils/addon-utils.ts @@ -24,8 +24,8 @@ export function isOrderedAddOn(addOn: ClusterAddOn) : boolean { * @returns */ export function dependable(...addOns: string[]) { - // eslint-disable-next-line @typescript-eslint/ban-types - return function (target: Object, key: string | symbol, descriptor: PropertyDescriptor) { + + return function (target: any, key: string | symbol, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function( ...args: any[]) { diff --git a/lib/utils/architecture-utils.ts b/lib/utils/architecture-utils.ts new file mode 100644 index 000000000..06e64db00 --- /dev/null +++ b/lib/utils/architecture-utils.ts @@ -0,0 +1,78 @@ +export enum ArchType { + ARM = "arm", + X86 = "x86", +} + +export const addonArchitectureMap = new Map(); + +/** + * Returns true of false depending on if the passed addon is + * supported by the passed architecture + * @param addOn, arch + * @returns boolean + */ + +export function isSupportedArchitecture(addOnName: string, arch: ArchType) : boolean | undefined { + + const archs = addonArchitectureMap.get(addOnName); + if (archs === undefined) { + if (arch === ArchType.X86) { + return true; + } + else { + return false; + } + } + return archs.includes(arch); +} + +export function validateSupportedArchitecture(addOnName: string, arch: ArchType, strictValidation?: boolean ) : void { + if (!isSupportedArchitecture(addOnName, arch)) { + if ((strictValidation) || (strictValidation === undefined)) { + throw new Error(`Addon ${addOnName} is not supported on architecture ${arch}`); + } + else { + console.warn(`Addon ${addOnName} is not supported on architecture ${arch}`); + } + } +} + +/** + * Decorator function that adds this metatdata to globalmap. + * @param arch + * @returns + */ + +// eslint-disable-next-line @typescript-eslint/ban-types +export function supportsX86(constructor: Function) { + const addonName = constructor.name; + addAddonArch(addonName, ArchType.X86); +} + +// eslint-disable-next-line @typescript-eslint/ban-types +export function supportsARM(constructor: Function) { + const addonName = constructor.name; + addAddonArch(addonName, ArchType.ARM); +} + +// eslint-disable-next-line @typescript-eslint/ban-types +export function supportsALL(constructor: Function) { + const addonName = constructor.name; + addAddonArch(addonName, ArchType.X86); + addAddonArch(addonName, ArchType.ARM); +} + +function addAddonArch(addonName: string, architecture: ArchType) { + if (addonArchitectureMap.has(addonName)) { + const value = addonArchitectureMap.get(addonName); + if ((value !== undefined) && !value.includes(architecture)) { + value.push(architecture); + } + else { + addonArchitectureMap.set(addonName, [architecture]); + } + } + else { + addonArchitectureMap.set(addonName, [architecture]); + } +} \ No newline at end of file diff --git a/lib/utils/index.ts b/lib/utils/index.ts index dd3519d97..99e58d216 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -1,4 +1,5 @@ export * from './addon-utils'; +export * from './architecture-utils'; export * from './cluster-utils'; export * from './constraints-utils'; export * from './context-utils'; diff --git a/mkdocs.yml b/mkdocs.yml index 36e1086f8..610143695 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,6 +16,7 @@ nav: - Teams: 'teams/teams.md' - EMR on EKS Team: 'teams/emr-eks-team.md' - AWS Batch on EKS Team: 'teams/aws-batch-on-eks-team.md' + - Bedrock Team: 'teams/geneai-team/bedrock-team.md' - Pipelines: 'pipelines.md' - AddOns: - Overview: 'addons/index.md' @@ -103,9 +104,11 @@ nav: - VPC Resource Providers: 'resource-providers/vpc-providers.md' - Builders: - Overview: 'builders/index.md' + - Bedrock Builder: 'builders/bedrock-builder.md' + - Graviton Builder: 'builders/graviton-builder.md' + - GPU Builder: 'builders/gpu-builder.md' - Observability Builder: 'builders/observability-builder.md' - Windows Builder: 'builders/windows-builder.md' - - GPU Builder: 'builders/gpu-builder.md' - Extensibility: 'extensibility.md' - API Reference: 'api' markdown_extensions: