Skip to content

Instantly share code, notes, and snippets.

@alongubkin
Last active October 26, 2022 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alongubkin/45f8aadab8ba325e148d03b3be8ad588 to your computer and use it in GitHub Desktop.
Save alongubkin/45f8aadab8ba325e148d03b3be8ad588 to your computer and use it in GitHub Desktop.
Create Kubernetes ServiceAccount with access to S3 using Pulumi
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as k8s from '@pulumi/kubernetes';
export interface S3ServiceAccountArgs {
oidcProvider: aws.iam.OpenIdConnectProvider;
namespace: pulumi.Input<string>;
readOnly: pulumi.Input<boolean>;
}
export default class S3ServiceAccount extends pulumi.ComponentResource {
public /*out*/ readonly name: pulumi.Output<string>;
public /*out*/ readonly serviceAccount: pulumi.Output<k8s.core.v1.ServiceAccount>;
constructor(name: string, args: S3ServiceAccountArgs, opts?: pulumi.ResourceOptions) {
super("pkg:index:S3ServiceAccount", name, {}, opts);
// Create the new IAM policy for the Service Account using the AssumeRoleWebWebIdentity action.
const serviceAccountAssumeRolePolicy = pulumi
.all([args.oidcProvider.url, args.oidcProvider.arn, args.namespace])
.apply(([url, arn, namespace]: string[]) =>
aws.iam.getPolicyDocument({
statements: [
{
actions: ['sts:AssumeRoleWithWebIdentity'],
conditions: [{
test: 'StringEquals',
values: [`system:serviceaccount:${namespace}:${name}`],
variable: `${url.replace('https://', '')}:sub`,
},],
effect: 'Allow',
principals: [{identifiers: [arn], type: 'Federated'}],
},
],
})
);
// Create a new IAM role that assumes the AssumeRoleWebWebIdentity policy.
const serviceAccountRole = new aws.iam.Role(name, {
assumeRolePolicy: serviceAccountAssumeRolePolicy.json,
});
// Attach the IAM role to an AWS S3 access policy.
new aws.iam.RolePolicyAttachment(name, {
policyArn: args.readOnly ?
'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess' :
'arn:aws:iam::aws:policy/AmazonS3FullAccess',
role: serviceAccountRole,
});
// Create a Service Account with the IAM role annotated to use with the Pod.
this.serviceAccount = pulumi.output(new k8s.core.v1.ServiceAccount(name, {
metadata: {
namespace: args.namespace,
name,
annotations: {
'eks.amazonaws.com/role-arn': serviceAccountRole.arn,
},
},
}, { provider: opts?.provider }));
this.name = pulumi.output(this.serviceAccount.metadata.name);
super.registerOutputs({
name: this.serviceAccount.metadata.name,
serviceAccount: this.serviceAccount,
});
}
}
@alongubkin
Copy link
Author

alongubkin commented Jun 5, 2021

Usage example:

const s3ServiceAccount = new S3ServiceAccount('s3-service-account', {
  namespace: namespace.metadata.name,
  oidcProvider: cluster.core.oidcProvider!,
  readOnly: true,
}, { provider: cluster.provider });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment