Skip to content

Instantly share code, notes, and snippets.

@jicowan
Created October 18, 2021 23:27
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 jicowan/66a3eedd76dfa223a302996e0c98bdb5 to your computer and use it in GitHub Desktop.
Save jicowan/66a3eedd76dfa223a302996e0c98bdb5 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"flag"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/eks"
"github.com/aws/aws-sdk-go-v2/service/iam"
"log"
"net/url"
)
const (
roleName = "forensics-role"
policyName = "forensics-policy"
)
func main() {
bucketArn := flag.String("bucketArn","arn:aws:s3:::jicowan-forensics", "Arn of the bucket")
namespace := flag.String("namespace", "forensics-system", "Service account namespace")
serviceAccount := flag.String("serviceAccount", "forensics", "Service account name")
clusterName := flag.String("clusterName", "bottlerocket", "Name of cluster")
flag.VisitAll(func (f *flag.Flag) {
if f.Value.String()=="" {
log.Fatalln(f.Name, "is not set")
}
})
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(context.TODO())
if cfg.Region == "" {
log.Fatalln("Could not find region in default profile")
}
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
}
iamPolicy := "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:PutObject\",\n \"s3:GetObject\"\n ],\n \"Resource\": \"" + *bucketArn + "*\"\n }\n ]\n}"
k8s := eks.NewFromConfig(cfg)
clusterOutput, err := k8s.DescribeCluster(ctx, &eks.DescribeClusterInput{
Name: clusterName,
})
if err != nil {
log.Fatalln(err)
}
oidcEndpointUrl := clusterOutput.Cluster.Identity.Oidc.Issuer
u, _ := url.Parse(*oidcEndpointUrl)
oidcEndpoint := u.Host + u.Path
log.Println(oidcEndpoint)
svc := iam.NewFromConfig(cfg)
oidcProviders, err := svc.ListOpenIDConnectProviders(ctx, &iam.ListOpenIDConnectProvidersInput{})
if err != nil {
log.Println(err)
}
p := oidcProviders.OpenIDConnectProviderList
oidcEndpointArn := p[0].Arn
log.Println(*oidcEndpointArn)
cpo, err := svc.CreatePolicy(ctx, &iam.CreatePolicyInput{
PolicyDocument: aws.String(iamPolicy),
PolicyName: aws.String(policyName),
Description: aws.String("allows writes to the specified s3 bucket"),
})
if err != nil {
log.Println(err)
}
trustPolicy := "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Federated\": \"" + *oidcEndpointArn + "\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Condition\": {\n \"StringEquals\": {\n \"" + oidcEndpoint + ":sub\": \"system:serviceaccount:" + *namespace + ":" + *serviceAccount + "\"\n }\n }\n }\n ]\n}"
cro, err := svc.CreateRole(ctx, &iam.CreateRoleInput{
AssumeRolePolicyDocument: aws.String(trustPolicy),
RoleName: aws.String(roleName),
Description: aws.String("Role for writing forensic data to an s3 bucket"),
})
if err != nil {
log.Println(err)
}
_, err = svc.AttachRolePolicy(ctx, &iam.AttachRolePolicyInput{
RoleName: aws.String(roleName),
PolicyArn: func(c iam.CreatePolicyOutput) *string {
if c.Policy.Arn == nil {
lpo, _ := svc.ListPolicies(ctx, &iam.ListPoliciesInput{Scope: "Not sure what to do here"})
log.Println(lpo.Policies[0].Arn)
return lpo.Policies[0].Arn
} else {
return c.Policy.Arn
}
}(*cpo),
})
if err != nil {
log.Println(err)
}
fmt.Println(aws.ToString(cro.Role.Arn))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment