Search code examples
kubernetesgradleamazon-s3amazon-eksservice-accounts

Unable to access AWS S3 Buckets Using AWS EKS Service Account


I'm working on a project where I need to list AWS S3 buckets in Java Spring Boot. Initially, I used secret and access keys passed through application.properties its working for me and the code looked like this:

@GetMapping("service2/getListOfS3Buckets")
public String getListOfS3Buckets() {
    AmazonS3 s3Client = AmazonS3ClientBuilder
            .standard()
            .withRegion(awsRegion)
            .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey)))
            .build();

    List<Bucket> buckets = s3Client.listBuckets();

    StringBuilder response = new StringBuilder("List of S3 Buckets:\n");
    for (Bucket bucket : buckets) {
        response.append(bucket.getName()).append("\n");
    }

    return response.toString();
}

However, I understand that this is not considered best practice, and I'd like to improve it by using an IAM role attached to a service account. I've attached the IAM role to the pod, but when I use the following code, I encounter an internal error:

  1. I created an IAM policy named "my-policy" with the necessary S3 permissions.

  2. I attached this policy to an IAM role named "my-role" using the following AWS CLI commands:

cat >my-policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:Describe*",
                "s3-object-lambda:Get*",
                "s3-object-lambda:List*"
            ],
            "Resource": "*"
        }
    ]
}
EOF
  

aws iam create-policy --policy-name my-policy --policy-document file://my-policy.json


eksctl create iamserviceaccount --name my-service-account --namespace kube-system --cluster my-cluster --role-name my-role \
    --attach-policy-arn arn:aws:iam::111122223333:policy/my-policy --approve

kubectl describe serviceaccount my-service-account -n kube-system


Name:                my-service-account
Namespace:           kube-system
Labels:              app.kubernetes.io/managed-by=eksctl
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::11111222222:role/my-role
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>


And this is my code

@GetMapping("service2/getListOfS3Buckets")
public String getListOfS3Buckets() {
    AmazonS3 s3Client = AmazonS3ClientBuilder
            .standard()
            .withRegion(awsRegion) // Specify your desired AWS region here
            .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
            .build();

    List<Bucket> buckets = s3Client.listBuckets();

    StringBuilder response = new StringBuilder("List of S3 Buckets:\n");
    for (Bucket bucket : buckets) {
        response.append(bucket.getName()).append("\n");
    }

    return response.toString();
}

I receive an internal error with the following message:

Request processing failed: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), SystemPropertiesCredentialsProvider: Unable to load AWS credentials from Java system properties (aws.accessKeyId and aws.secretKey), WebIdentityTokenCredentialsProvider: To use assume role profiles the aws-java-sdk-sts module must be on the class path., com.amazonaws.auth.profile.ProfileCredentialsProvider@59639381: profile file cannot be null, com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@39201cc7: Failed to connect to service endpoint:]

I need assistance in resolving this issue and successfully using the IAM role attached to the service account for AWS authentication. Any guidance or suggestions would be greatly appreciated.


Solution

  • Error says that you haven't annotated the service account with proper IAM role.

    Steps to resolve this issue:

    1. Create an IAM Role and attach the s3 access policy.
    2. Annotate the service account with the above created IAM role.

    Please follow the steps(1,2,3) in this document https://repost.aws/knowledge-center/eks-restrict-s3-bucket