spring-cloud-aws icon indicating copy to clipboard operation
spring-cloud-aws copied to clipboard

Error when trying to use spring.cloud.aws.credentials.profile

Open jndietz opened this issue 2 years ago • 4 comments

Type: Bug

Component:

Credentials

Describe the bug Using Spring Boot 3.1.3 with Cloud 2022.0.4

Sample I have the following in my application-local.yml file:

spring:
  cloud:
    aws:
      credentials:
        profile: some-profile-name

I assume that this should be enough to configure the AwsCredentialsProvider, but I get the following error:

Description:

Failed to bind properties under 'spring.cloud.aws.credentials.profile' to io.awspring.cloud.autoconfigure.core.Profile:

    Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [@org.springframework.lang.Nullable io.awspring.cloud.autoconfigure.core.Profile]

To work around this, I created the @Bean manually:

@Configuration
@Profile("local")
public class LocalAwsCredentialConfiguration {

    @Value("${spring.cloud.aws.credentials.profile}")
    String profile;

    @Bean
    public AwsCredentialsProvider localAwsCredentialsProvider() {
        return ProfileCredentialsProvider
                .builder()
                .profileName(profile)
                .build();
    }
}

Is the above error expected with trying to configure a credential profile in a "YAML-only" fashion? I read through the docs here:

https://docs.awspring.io/spring-cloud-aws/docs/2.4.1/reference/html/index.html#configuring-credentials

jndietz avatar Sep 11 '23 13:09 jndietz

Hey, noob here. Im also trying to set up spring-cloud-aws-parameter-store and find myself in the same situation. Tried to replicate your solution but still doesn't work. Would care to tell me if you were also using spring-cloud-aws-starter besides spring-cloud-aws-starter-parameter-store or it doesn't matter?

HenriqueDelben avatar Oct 19 '23 21:10 HenriqueDelben

The property name in Spring Cloud AWS 3.x is spring.cloud.aws.credentials.profile.name. Can you try with this?

maciejwalkowiak avatar Oct 23 '23 14:10 maciejwalkowiak

I'm using Spring Cloud AWS version 3.0.2 and there's no such property like spring.cloud.aws.credentials.profile.name (at least this is what intellij is saying)

Here is my POM.XML file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>teste2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>teste2</name>
    <description>teste2</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.awspring.cloud</groupId>
                <artifactId>spring-cloud-aws-dependencies</artifactId>
                <version>3.0.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-aws-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-aws-starter-parameter-store</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Here's my application.properties:

spring.config.import=aws-parameterstore:/dev/cashew
spring.cloud.aws.credentials.profile.name=default
logging.level.io.awspring.cloud=debug

When I try to test it, it returns this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testeController': Injection of autowired dependencies failed
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:498) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1416) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:597) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:950) ~[spring-context-6.0.13.jar:6.0.13]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616) ~[spring-context-6.0.13.jar:6.0.13]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.5.jar:3.1.5]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:738) ~[spring-boot-3.1.5.jar:3.1.5]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:440) ~[spring-boot-3.1.5.jar:3.1.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-3.1.5.jar:3.1.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.5.jar:3.1.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-3.1.5.jar:3.1.5]
        at com.example.teste2.Teste2Application.main(Teste2Application.java:10) ~[classes/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.1.5.jar:3.1.5]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'kms.publickey' in value "${kms.publickey}"
        at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-6.0.13.jar:6.0.13]
        at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-6.0.13.jar:6.0.13]
        at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-6.0.13.jar:6.0.13]
        at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-6.0.13.jar:6.0.13]
        at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:200) ~[spring-context-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:918) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1358) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:764) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:747) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145) ~[spring-beans-6.0.13.jar:6.0.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:492) ~[spring-beans-6.0.13.jar:6.0.13]
        ... 22 common frames omitted

This is my TesteController where Im trying to inject it:

package com.example.teste2;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TesteController {

    @Value("${kms.publickey}")
    private String teste;

    @GetMapping("/teste")
    public String teste() {
        return teste;
    }
}

HenriqueDelben avatar Oct 23 '23 15:10 HenriqueDelben

The spring.cloud.aws.credentials.profile.name property exists it's just that because in io.awspring.cloud.autoconfigure.core.CredentialsProperties the profile field is an io.awspring.cloud.autoconfigure.core.Profile that IntelliJ isn't able to resolve it.

If you, for example, shorten the value to spring.cloud.aws.credentials.profile and use IntelliJ to navigate to the source it will jump you to io.awspring.cloud.autoconfigure.core.CredentialsProperties.

@maciejwalkowiak - I believe that all that needs to be done is to add @NestedConfigurationProperty to the profile field in CredentialsProperties to resolve this. (I came here looking for this)

adase11 avatar Nov 14 '23 20:11 adase11

for anyone who stumbles on this and still on the older 3.1.x you can specify your AWS credentials profile by setting AWS_PROFILE=your_aws_profile_name environment variable when running app/tests.

dalegaspi avatar Aug 22 '24 01:08 dalegaspi