0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring Boot × AWS Secrets ManagerでRDSの認証情報を安全に取得する方法

0
Posted at

背景

Spring Boot で構成したファイルから、DBに接続するため、Secrets Manager からDB認証情報を取得しようとした際に、結構苦戦したので、修正手順を記載します。

前提

・RDS作成済み
・EC2作成とjavaのインストール済み
・Secrets Manager に認証情報登録済み

AwsSecretsManagerConfig.java の作成

以下の記述を行い、AWS SDKを使用してSecrets Manager から認証情報を取得します。

@Configuration
@ConditionalOnMissingBean(DataSource.class)
public class AwsSecretsManagerConfig {

    private static final Logger logger = LoggerFactory.getLogger(AwsSecretsManagerConfig.class);

    private final Environment env;

    public AwsSecretsManagerConfig(Environment env) {
        this.env = env;
    }

    @Bean
    public DataSource dataSource() {

        // ✅ Springのapplication.propertiesから取得
        String url = env.getProperty("spring.datasource.url", "jdbc:h2:mem:testdb");
        String driver = env.getProperty("spring.datasource.driver-class-name", "org.h2.Driver");

        String username = null;
        String password = null;

        String secretId = env.getProperty("AWS_SECRET_ID");

        if (secretId != null && !secretId.isBlank()) {
            try (SecretsManagerClient client = buildClient()) {

                GetSecretValueRequest req = GetSecretValueRequest.builder()
                        .secretId(secretId)
                        .build();

                GetSecretValueResponse resp = client.getSecretValue(req);
                String secretString = resp.secretString();

                if (secretString != null && !secretString.isBlank()) {
                    ObjectMapper om = new ObjectMapper();
                    JsonNode node = om.readTree(secretString);

                    username = node.has("username") ? node.get("username").asText() : null;
                    password = node.has("password") ? node.get("password").asText() : null;

                    logger.info("Loaded DB credentials from Secrets Manager (secretId={})", secretId);
                }

            } catch (Exception e) {
                logger.error("Failed to load secret {}: {}", secretId, e.getMessage());
                throw new RuntimeException("Unable to load DB credentials from Secrets Manager", e);
            }
        } else {
            throw new RuntimeException("AWS_SECRET_ID is not set");
        }

        // ✅ DataSource作成
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setDriverClassName(driver);

        // デバッグ用ログ(超重要)
        logger.info("DB URL: {}", url);
        logger.info("DB USER: {}", username);

        return ds;
    }

    private SecretsManagerClient buildClient() {
        String region = env.getProperty("AWS_REGION");

        if (region != null && !region.isBlank()) {
            return SecretsManagerClient.builder()
                    .region(Region.of(region))
                    .build();
        }

        return SecretsManagerClient.create();
    }
}

AWS SDK(バージョン2系)のSecrets Manager用ライブラリを使用して取得するので、pom.xmlに依存関係の追加を忘れず!

pom.xml
		<!-- Use AWS SDK v2 Secrets Manager via application code instead of awspring starter (awspring artifact not available in Maven Central). -->
		<dependency>
			<groupId>software.amazon.awssdk</groupId>
			<artifactId>secretsmanager</artifactId>
			<version>2.20.66</version>
		</dependency>

IAMロール追加

EC2のIAMロールを設定し、以下のアクションを許可します。
Secrets Managerから認証情報を取得するためのアクションです。

 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"

application.properties でDB設定

接続先のDBを設定します。

application.properties
spring.datasource.url=<RDSのエンドポイント>:3306/<テーブル名>
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

/etc/systemd/system/配下にunitファイルを作成し、環境変数を追加

※ unitファイルとは:Linuxでサービスやプロセスをどう起動・管理するかを定義する設定ファイル

[Unit]
Description=sample
After=network.target

[Service]
User=<ユーザー名>
Environment=AWS_SECRET_ID=<シークレットID>
Environment=AWS_REGION=<シークレットのあるリージョン>
(下記省略)

systemd反映&起動

sudo systemctl daemon-reload
sudo systemctl start <unitファイル名>
sudo systemctl status <unitファイル名>

journalctl コマンドを実行し、JDBC URL が表示されていることを確認

※ journalctl : サービスやプロセスを管理する仕組みであるsystemdのログを見るコマンド
スクリーンショット 0008-03-29 9.20.43.png

Tableが作成されていることも確認

image.png

以上でSecrets Manager から認証情報を取得し、DBへの接続が完了しました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?