Как мне предоставить учетные данные AWS через свойства Java для источника свойств Spring хранилища параметров AWS?
Из документов: http://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.0.RC2/single/spring-cloud-aws.html
Поддержка конфигурации хранилища параметров использует контекст начальной загрузки для настройки клиента AWSSimpleSystemsManagement по умолчанию, который использует com.amazonaws.auth.DefaultAWSCredentialsProviderChain и com.amazonaws.regions.DefaultAwsRegionProviderChain
Документы для цепочки поставщиков: https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html
Я надеюсь не использовать переменные окружения или свойства командной строки, так как есть большая вероятность, что они попадут в журналы где-то в prod. Лучший вариант, который я вижу, это использовать файл.properties. Согласно первой ссылке, поскольку модуль загружается в контексте начальной загрузки, я мог бы представить, что "Spring" может сделать это, включив эти свойства в файл bootstrap.properties (согласно документам spring-cloud: https://cloud.spring.io/spring-cloud-static/spring-cloud.html)
Итак, мой проект выглядит так:
/src/main/resources/bootstrap.properties
aws.accessKeyId = SECRET
aws.secretKey = ALSOSECRET
pom.xml
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
<version>2.0.0.RC2</version>
</dependency>
</dependencies>
....
Обратите внимание, что я также раскрываю переменную среды AWS_REGION, это было первое препятствие, которое нужно преодолеть. Я использую Java 8 и могу повторить приведенное ниже поведение, которое выполняется как из Eclipse, так и из командной строки Maven.
При запуске я получаю эту трассировку стека:
2018-06-11 13:20:57.092 INFO 2272 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@359f7cdf: startup date [Mon Jun 11 13:20:57 CDT 2018]; root of context hierarchy
2018-06-11 13:20:57.613 INFO 2272 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$459ef732] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.1.RELEASE)
2018-06-11 13:21:00.301 ERROR 2272 --- [ main] c.a.p.AwsParamStorePropertySourceLocator : Fail fast is set and there was an error reading configuration from AWS Parameter Store:
Unable to load AWS credentials from any provider in the chain
2018-06-11 13:21:00.308 ERROR 2272 --- [ main] o.s.boot.SpringApplication : Application run failed
com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:131) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1164) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:762) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:724) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) ~[aws-java-sdk-core-1.11.251.jar:na]
at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.doInvoke(AWSSimpleSystemsManagementClient.java:6573) ~[aws-java-sdk-ssm-1.11.251.jar:na]
at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.invoke(AWSSimpleSystemsManagementClient.java:6549) ~[aws-java-sdk-ssm-1.11.251.jar:na]
at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.executeGetParametersByPath(AWSSimpleSystemsManagementClient.java:4204) ~[aws-java-sdk-ssm-1.11.251.jar:na]
at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.getParametersByPath(AWSSimpleSystemsManagementClient.java:4180) ~[aws-java-sdk-ssm-1.11.251.jar:na]
at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySource.getParameters(AwsParamStorePropertySource.java:67) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySource.init(AwsParamStorePropertySource.java:52) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySourceLocator.create(AwsParamStorePropertySourceLocator.java:111) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySourceLocator.locate(AwsParamStorePropertySourceLocator.java:94) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:94) ~[spring-cloud-context-2.0.0.RC2.jar:2.0.0.RC2]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:633) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:373) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at com.company.app.App.main(App.java:10) [classes/:na]
Должен ли я ожидать, что этот модуль будет иметь видимость свойств из bootstrap.properties? Как еще я должен предоставить свойства для контекста начальной загрузки?
1 ответ
Я надеюсь не использовать переменные окружения или свойства командной строки, так как есть большая вероятность, что они попадут в журналы где-то в prod.
На самом деле, AWS достаточно хорош, чтобы справиться с большей частью грязной работы за вас. Вы обеспокоены тем, что ваши учетные данные будут отображаться в виде открытого текста в журналах, сейчас и навсегда, и вы хотите сохранить свои учетные данные в файле, который будет управляться какой-либо системой версий / репо. AWS признает, что это возможный вариант, но на самом деле утверждает, что не считает его лучшим решением из-за большого объема работы.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html
Ваши разработчики могут хранить учетные данные AWS непосредственно в экземпляре EC2 и разрешать приложениям в этом экземпляре использовать эти учетные данные. Но тогда разработчики должны будут управлять учетными данными и гарантировать, что они безопасно передают учетные данные каждому экземпляру и обновляют каждый экземпляр EC2, когда пришло время повернуть учетные данные. Это много дополнительной работы.
Вы можете настроить AWS на использование ролей IAM для предоставления временных учетных данных для вашего экземпляра EC2 при развертывании приложения. Эти роли ограничены доступом, который вы определяете, и истекают через короткий промежуток времени, возможно, самое большее несколько часов.
Сообщение об ошибке, которое вы опубликовали, вообще не произойдет в вашем правильно настроенном экземпляре EC2. Для запуска в локальной тестовой среде или вне облака вы можете предоставить учетные данные в хранилище.aws/credentials без необходимости предоставления каких-либо учетных данных для доступа к вашим блокам QA/PROD EC2, поскольку путь.aws/credentials не не проверял до тех пор, пока после переменных среды.
Это приводит к немедленным преимуществам для вашей безопасности и здравомыслия: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html
Вам не нужно распространять или встраивать долгосрочные учетные данные безопасности AWS вместе с приложением.
Вы можете предоставить пользователям доступ к своим ресурсам AWS, не определяя для них идентификатор AWS. Временные учетные данные являются основой для федерации ролей и удостоверений.
Временные учетные данные безопасности имеют ограниченный срок службы, поэтому вам не нужно поворачивать их или явно отзывать их, когда они больше не нужны. После истечения срока действия временных учетных данных они не могут быть повторно использованы. Вы можете указать срок действия учетных данных до максимального ограничения.