<p>Aws sdk getting instance credential from eks instead of ec2</p>
<p>I'm using spring cloud aws to send send messages to an sns, and local the <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html" rel="nofollow noreferrer">credential chain</a> work fine with a .aws/credentials file. However in the cloud it is not being that easy.</p>
<p>For cloud deployment, we are using IAM roles for service accounts. In the SDK <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html" rel="nofollow noreferrer">doc</a>, the credential chain assumes this role if no other is found.</p>
<p>This would be the easy way, but it doesn't happen, when spring is up it somehow is taking the role that is assigned to node eks, which in theory it shouldn't even fill, which is not correct and causes a permission error when i use sns.</p>
<pre><code>software.amazon.awssdk.services.sns.model.AuthorizationErrorException: User: arn:aws:sts::*******:assumed-role/eksctl-*******-eks-qa-nodegroup-spo-NodeInstanceRole-*******/i-******* is not authorized to perform: SNS:ListTopics
</code></pre>
<p>I've tried several ways to get it right, including</p>
<pre><code>@Bean
@Primary
public AmazonSNS amazonSns() {
    return AmazonSNSClientBuilder.standard()
            .withCredentials(new InstanceProfileCredentialsProvider())
            .build();
}


cloud:
      aws:
        credentials:
          use-default-aws-credentials-chain: true
</code></pre>
<p>and a few others.</p>
<p>I isolated the error, and the sdk v1 is responsible. I uploaded a code version with the pure sdk v2 without modifying anything in the environment, and it worked as it should, using the credential chain and getting the correct role.</p>
<p>I already checked this <a href="https://stackoverflow.com/a/70028461/13041893">answer</a>, and the version used by spring is 1.11.951 and with the pure sdk I used 1.12.142 . The minimum version by the <a href="https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html" rel="nofollow noreferrer">doc</a> is 1.11.704</p>
<p>Using the pure sdk v2 is a bit laborious and unnecessary if spring already provides this implementation, it will use it by default in <a href="https://spring.io/blog/2021/03/17/spring-cloud-aws-2-3-is-now-available" rel="nofollow noreferrer">spring cloud aws V3.0</a></p>
<p>My gradle.build</p>
<pre><code>     plugins {
        id 'org.springframework.boot' version '2.6.2'
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id 'java'
    }

    group = 'com.multilaser.worker'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '17'

    ext {
        set('springCloudVersionAws', &quot;2.3.2&quot;)
    }

    repositories {
       mavenCentral()
       mavenLocal()
   }

     configurations {
        compileOnly {
           extendsFrom annotationProcessor
       }
   }

   dependencies {
       implementation 'org.springframework.boot:spring-boot-starter'
       testImplementation 'org.springframework.boot:spring-boot-starter-test'
       implementation 'io.awspring.cloud:spring-cloud-starter-aws'
       implementation 'io.awspring.cloud:spring-cloud-starter-aws-messaging'
       implementation 'io.awspring.cloud:spring-cloud-aws-autoconfigure'
       compileOnly 'org.projectlombok:lombok'
       annotationProcessor 'org.projectlombok:lombok'
       implementation 'org.springframework.boot:spring-boot-starter-actuator'
       annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
       }

       dependencyManagement {
          imports {
             mavenBom &quot;io.awspring.cloud:spring-cloud-aws-dependencies:${springCloudVersionAws}&quot;
        }
   }
</code></pre>
<p>depoy.yml</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: ----
  namespace: ---
  labels:
    app: ---
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ---
  template:
    metadata:
      labels:
        app: ---
    spec:
      serviceAccountName: ----
      containers:
      - name: ---
        image: ---
        imagePullPolicy: Always
        resources:
          requests:
            memory: &quot;256Mi&quot;
            cpu: &quot;80m&quot;
          limits:
            memory: &quot;800Mi&quot;
            cpu: &quot;500m&quot;
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /actuator/health
            port: 8080
            httpHeaders:
            - name: X-Custom-Header
              value: ReadinessProbe
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 10
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /actuator/health
            port: 8080
            httpHeaders:
            - name: X-Custom-Header
              value: LivenessProbe
          initialDelaySeconds: 35
          periodSeconds: 15
          successThreshold: 1
          timeoutSeconds: 10
        envFrom:
          - configMapRef:
              name: ---
          - secretRef:
              name: ---
        ports:
        - containerPort: 8080
        - containerPort: 5005
</code></pre>

Bryan Motta
<p>Adding the lib aws-java-sdk-sts to the project solved the problem</p>
<pre><code>implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.11.951'
</code></pre>
