Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add S3 CSI Driver IAM policy as blueprints addon #1093

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions docs/addons/s3-csi-driver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# S3 CSI Driver Addon

The S3 CSI Driver Addon integrates Amazon S3 with your Kubernetes cluster, allowing you to use S3 buckets as persistent storage for your applications.

## Prerequisites

- The S3 bucket must be created in AWS separately as the driver uses the S3 bucket for storage, but it does not create it.
- The S3 bucket must have a bucket policy that allows the EKS cluster to access the bucket.

## Usage

```typescript
import { S3CsiDriverAddon } from '@aws-quickstart/eks-blueprints';

const addOns = [
new S3CsiDriverAddon({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jesperalmstrom minor: must be S3CSIDriverAddOn not S3CsiDriverAddon

s3BucketName: 'my-s3-bucket',
}),
// other addons
];

const blueprint = EksBlueprint.builder()
.addOns(...addOns)
.build(app, 'my-stack');
```

## Configuration

You can customize the S3 CSI Driver Addon by passing configuration options:

```typescript
new S3CsiDriverAddon({
s3BucketName: 'my-s3-bucket',
});
```

## Use in EKS Cluster

Once installed, you can create PersistentVolume and PersistentVolumeClaim resources that use the S3 CSI Driver:

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: s3-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
csi:
driver: s3.csi.aws.com
volumeHandle: my-s3-bucket
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: s3-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: s3-pv
```

## References

- [Amazon S3 CSI Driver Source](https://github.com/awslabs/mountpoint-s3-csi-driver)
- [Amazon EKS S3 CSI Driver Documentation](https://docs.aws.amazon.com/eks/latest/userguide/s3-csi.html)
1 change: 1 addition & 0 deletions lib/addons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export * from './neuron';
export * from './nginx';
export * from './opa-gatekeeper';
export * from './prometheus-node-exporter';
export * from './s3-csi-driver';
export * from './secrets-store';
export * from './secrets-store/csi-driver-provider-aws-secrets';
export * from './secrets-store/secret-provider';
Expand Down
25 changes: 25 additions & 0 deletions lib/addons/s3-csi-driver/iam-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as iam from 'aws-cdk-lib/aws-iam';

export function getS3DriverPolicyStatements(s3BucketName: string): iam.PolicyStatement[] {
// new IAM policy to grand access to S3 bucket
// https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#iam-permissions
const s3BucketArn = `arn:aws:s3:::${s3BucketName}`;
return [
new iam.PolicyStatement({
sid: 'S3MountpointFullBucketAccess',
actions: [
"s3:ListBucket"
],
resources: [s3BucketArn]
}),
new iam.PolicyStatement({
sid: 'S3MountpointFullObjectAccess',
actions: [
"s3:GetObject",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject"
],
resources: [`${s3BucketArn}/*`]
})];
}
85 changes: 85 additions & 0 deletions lib/addons/s3-csi-driver/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Construct } from "constructs";
import { ClusterInfo } from "../../spi";
import { HelmAddOn, HelmAddOnUserProps } from "../helm-addon";
import * as iam from 'aws-cdk-lib/aws-iam';
import { createNamespace, setPath, supportsALL } from "../../utils";
import { getS3DriverPolicyStatements } from "./iam-policy";

const S3_CSI_DRIVER_SA = 's3-csi-driver-sa';
const S3_CSI_DRIVER = 's3-csi-driver';
const S3_CSI_DRIVER_RELEASE = 's3-csi-driver-release';
const S3_DRIVER_POLICY = 's3-csi-driver-policy';

/**
* Configuration options for the add-on.
*/
export interface S3CSIDriverAddOnProps extends HelmAddOnUserProps {
/**
* ARN of the S3 bucket to be used by the driver
*/
s3BucketName: string;
/**
* Create Namespace with the provided one (will not if namespace is kube-system)
*/
createNamespace?: boolean
}

/**
* Defaults options for the add-on
*/
const defaultProps: HelmAddOnUserProps & S3CSIDriverAddOnProps = {
jesperalmstrom marked this conversation as resolved.
Show resolved Hide resolved
chart: S3_CSI_DRIVER,
name: S3_CSI_DRIVER,
namespace: 'kube-system',
release: S3_CSI_DRIVER_RELEASE,
version: 'v1.9.0',
repository: 'https://github.com/awslabs/mountpoint-s3-csi-driver',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be 'https://awslabs.github.io/mountpoint-s3-csi-driver' which is a proper helm repo as opposed to the source repo. Otherwise helm version validation fails.
See https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/docs/install.md#helm

createNamespace: false,
s3BucketName: ''
};

@supportsALL
export class S3CSIDriverAddOn extends HelmAddOn {

readonly options: S3CSIDriverAddOnProps;

constructor(props: S3CSIDriverAddOnProps) {
super({ ...defaultProps as any, ...props });
this.options = this.props as S3CSIDriverAddOnProps;
}

deploy(clusterInfo: ClusterInfo): Promise<Construct> {
// Create service account and policy
const cluster = clusterInfo.cluster;
const serviceAccount = cluster.addServiceAccount(S3_CSI_DRIVER_SA, {
name: S3_CSI_DRIVER_SA,
namespace: this.options.namespace,
});

const s3BucketPolicy = new iam.Policy(cluster, S3_DRIVER_POLICY, {
statements:
getS3DriverPolicyStatements(this.options.s3BucketName)
});
serviceAccount.role.attachInlinePolicy(s3BucketPolicy);

// Create namespace
if (this.options.createNamespace) {
const ns = createNamespace(this.options.namespace!, cluster, true);
serviceAccount.node.addDependency(ns);
}

// setup value for helm chart
const chartValues = populateValues(this.options);

const s3CsiDriverChart = this.addHelmChart(clusterInfo, chartValues, true, true);
s3CsiDriverChart.node.addDependency(serviceAccount);
return Promise.resolve(s3CsiDriverChart);
}
}

function populateValues(helmOptions: S3CSIDriverAddOnProps): any {
const values = helmOptions.values ?? {};
setPath(values, 'node.serviceAccount.create', false);
setPath(values, 'node.tolerateAllTaints', true);
return values;
}
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ nav:
- Pixie: 'addons/pixie.md'
- Prometheus Node Exporter: 'addons/prometheus-node-exporter.md'
- Rafay: 'addons/rafay.md'
- S3 CSI Driver: 'addons/s3-csi-driver.md'
- Secrets Store: 'addons/secrets-store.md'
- Snyk: 'https://github.com/snyk-partners/snyk-monitor-eks-blueprints-addon'
- SSM Agent: 'addons/ssm-agent.md'
Expand Down