30 Ağustos 2022 Salı

SpringCloud AWS Secrets Manager - AWS Secrets Manager'dan Bilgileri Alır

Giriş
AWS secret değerlerini actuator ile env altında görebiliriz.
http://localhost:8080/actuator/env
SpringCloud AWS Systems Manager kullanımına çok benziyor

Maven
Şu satırı dahil ederiz
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.awspring.cloud</groupId>
      <artifactId>spring-cloud-aws-dependencies</artifactId>
      <version>3.0.0-M2</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
</dependencies>

<dependency>
  <groupId>io.awspring.cloud</groupId>
  <artifactId>spring-cloud-aws-starter-secrets-manager</artifactId>
</dependency>
Gradle
Şu satırı dahil ederiz
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter'
  implementation('io.awspring.cloud:spring-cloud-starter-aws-secrets-manager-config:2.4.2')
}
application.yaml Dosyası
spring.config.import AWS'ten parametreleri çeker ve bunları Spring’in ortam değişkenlerine (environment properties) ekler

Örnek
Maven ile şöyle yaparız
<dependency>
     <groupId>com.amazonaws</groupId>
     <artifactId>aws-java-sdk-secretsmanager</artifactId>
  </dependency>
  <dependency>
     <groupId>com.amazonaws.secretsmanager</groupId>
     <artifactId>aws-secretsmanager-jdbc</artifactId>
     <version>1.0.5</version>
  </dependency>
application.properties ile şöyle yaparız
spring.datasource.url = (name/path of your secrets manager)
spring.datasource.username = (name/path of your secrets manager)
spring.datasource.driver-class-name = com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
Örnek - Other Secret Type

Örnek
yaml dosyası şöyle olsun. 3 tane farklı secret dosyası içinde sev/value çiftleri tanımladık.
spring:
  config:
    import:
      - aws-secretsmanager:dev/my-app/database-creds
      - aws-secretsmanager:dev/my-app/oauth-creds
      - optional:aws-secretsmanager:dev/my-app/some-other-creds
Bu çiftlerin herhangi birine @Value ile erişebiliriz. Şöyle yaparız
@SpringBootApplication
public class SpringBootAwsSecretsApplication implements CommandLineRunner {

  @Value("${dbUser}")
  private String dbUser;

  @Value("${dbPassword}")
  private String dbPassword;
  ...
}
Örnek
Şöyle bir secret yaratalım
aws secretsmanager create-secret 
  --name /secret/db-credential 
  --secret-string '{"dbuser": "user1", "dbpassword": "password"}'
Şöyle yaparız. spring/cloud/config/import ile secret ismi belirtiliyor. Secret içindeki dbuser ve dbpassword değişkenleri kullanılıyor. AWS için kullanılan profile ismi "personal"
# actuator configuration
management:
  endpoints:
    web:
      exposure:
        include:
        - env
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/database
    username: ${dbuser}
    password: ${dbpassword}
  jpa:
    hibernate:
      ddl-auto: create

#  AWS configuration
  cloud:
    aws:
      secretsmanager:
        region: eu-central-1
          
      credentials:
        profile:
          name: personal
  config:
    import:
       - aws-secretsmanager:/secret/db-credential
       - optional:aws-secretsmanager:/secrets/optional-secret
Localstack İle Unit Test
Docker compose ile Localstack'i çalıştırmak için şöyle yaparız
version: "3.8"

services:
  localstack:
    image: localstack/localstack
    ports:
      - "4566:4566"            # LocalStack endpoint
    environment:
      - DOCKER_HOST=unix:///var/run/docker.sock
      - DEFAULT_REGION=eu-central-1
    volumes:
      - ./localstack-script:/docker-entrypoint-initaws.d
      - /var/run/docker.sock:/var/run/docker.sock
localstack-script/script.sh içinde şöyle yaparız. awslocal localstack tarafından sağlanır ve aws komutu için bir wrapper
awslocal secretsmanager create-secret 
  --name /secret/spring-boot-app 
  --secret-string '{"property1": "property1-value", "property2": "property2-value"}'

awslocal secretsmanager create-secret 
  --name /secret/db-credential 
  --secret-string '{"dbuser": "user1", "dbpassword": "password"}'
test için application.properties şöyledir
spring:
  cloud:
     aws:
      secretsmanager:
        region: eu-central-1
        endpoint: http://localhost:4566
      credentials:
        access-key: none
        secret-key: none
Test içinde şöyle yaparız. Burada @DynamicPropertySource kullanılmıyor
@SpringBootTest
@AutoConfigureMockMvc
class ApplicationIT {

  @Autowired
  MockMvc mockMvc;

  @Container
  private static LocalStackContainer localStackContainer = 
    new LocalStackContainer(DockerImageName.parse("localstack/localstack"))
      .withCopyFileToContainer(MountableFile.forClasspathResource("script.sh"),
                    "/docker-entrypoint-initaws.d/")
      .withServices(LocalStackContainer.Service.SECRETSMANAGER);

  @BeforeAll
  static void beforeAll() throws IOException, InterruptedException {
    System.setProperty("spring.cloud.aws.secretsmanager.endpoint",
      localStackContainer.getEndpointOverride(
        LocalStackContainer.Service.SECRETSMANAGER).toString());

    System.setProperty("spring.cloud.aws.secretsmanager.region", 
      localStackContainer.getRegion());
    System.setProperty("spring.cloud.aws.credentials.access-key", "none");
    System.setProperty("spring.cloud.aws.credentials.secret-key", "none");
  }
  ...
 
}
   







Hiç yorum yok:

Yorum Gönder