Aws sdk getting instance credential from eks instead of ec2
I'm using spring cloud aws to send send messages to an sns, and local the credential chain work fine with a .aws/credentials file. However in the cloud it is not being that easy.
For cloud deployment, we are using IAM roles for service accounts. In the SDK doc, the credential chain assumes this role if no other is found.
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.
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
I've tried several ways to get it right, including
@Bean
@Primary
public AmazonSNS amazonSns() {
return AmazonSNSClientBuilder.standard()
.withCredentials(new InstanceProfileCredentialsProvider())
.build();
}
cloud:
aws:
credentials:
use-default-aws-credentials-chain: true
and a few others.
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.
I already checked this answer, 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 doc is 1.11.704
Using the pure sdk v2 is a bit laborious and unnecessary if spring already provides this implementation, it will use it by default in spring cloud aws V3.0
My gradle.build
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', "2.3.2")
}
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 "io.awspring.cloud:spring-cloud-aws-dependencies:${springCloudVersionAws}"
}
}
depoy.yml
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: "256Mi"
cpu: "80m"
limits:
memory: "800Mi"
cpu: "500m"
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
CodePudding user response:
Adding the lib aws-java-sdk-sts to the project solved the problem
implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.11.951'
