Secrets Managerをrubyのコードから実行してみる

## はじめに
前からSecrets Managerを触ってみたいと思っていたので、今回使ってみることにしました。

## secret managerとは
公式より
>AWS Secrets Manager は、データベース認証情報、アプリケーション認証情報、OAuth トークン、API キー、およびその他のシークレットをライフサイクルを通じて管理、取得、ローテーションするのに役立ちます。多くの AWS サービスは、Secrets Manager でシークレットを保存して使用します。

例えば、Secrets Mangerを使用すると、APIによってデータベース認証情報を取得することができ、なおかつ鍵の更新を自動で行うことができます。

https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html

## Secrets Managerの設定方法
実際に、Secrets Managerの設定をして、使用してみたいと思います。
以下の手順でやっていきます。

**新しいシークレットを保存する**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/87b3bdc2-5a2e-8d88-cefe-86fe359c5248.png)

**シークレットタイプを選択**
今回はRDSのシークレットを保存したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/81dd64a8-81dd-a19f-c194-5fa0ad2b9abb.png)

**認証情報を入力**
認証情報はRDSを作成する際に、設定したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/efe8c33a-de95-1da4-8019-2b0db204817d.png)

**暗号化キー**
`aws/secretsmanager`はデフォルトの暗号化キーです。
自分で新しいキーを追加することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/a6050863-8a31-e37d-fab9-851c31e368e1.png)

**データベースを選択**
認証情報を保存するデータベースを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/4dd2a04a-926a-c0a9-36ef-6c7700d00daa.png)

**シークレットの名前を設定**
シークレットの名前を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/0ffe1240-645d-d564-1619-6069bce477d8.png)

**ローテーションスケジュール**
今回はスケジュール式を選択します。rate(30 days)で設定を行います。
- スケジュール式ビルダーはCron 式を使用し、スケジュール式より詳細なローテーションスケジュールを作成できる
- スケジュール式はRate 式を使用し、一定の時間間隔や日数間隔で繰り返されるローテーションスケジュールを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/a55bf754-d76b-ad11-46eb-fe3b564a6774.png)

**ローテーション関数**
lamda関数を自動で作成してくれて、キーのローテーション処理を行ってくれます。
関数名は必須なので入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/48401c7b-e17d-f86a-e5f0-aa28de334695.png)

**サンプルコード**
認証情報を取得するサンプルコードが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/3e26ec2d-6eb0-85a6-5168-a89a3810dc85.png)

以上の設定を行い、保存します。


## 認証情報の取得
実際に認証情報の取得を行ってみます。

### CLIで取得
まずはCLIでコマンドを入力し、認証情報を取得してみます。
region名とsecret-idは自分の環境に合わせてください。
secret-idはシークレットの名前で設定したものです。
```sh
$ aws secretsmanager get-secret-value --region ap-northeast-1 --secret-id sample/demo/DBkey

{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:<aws_account_id>:secret:sample/demo/DBkey-33tNM3",
    "Name": "sample/demo/DBkey",
    "VersionId": "028acae4-773f-4ec3-8b09-0603d1fe9cfd",
    "SecretString": "{\"username\":\"*****\",\"password\":\"********\",\"engine\":\"mysql\",\"host\":\"*********************\",\"port\":3306,\"dbInstanceIdentifier\":\"database-1\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": "2024-07-11T02:51:41.308000+09:00"
}
```

### rubyコードから認証情報を取得する
以下のようなコードを入力して実行します。
access_key_id,secret_access_keyをハードコーディングしていますが、確認のためなのでお許しください。
実際は環境変数で指定するのが良いです。
```rb
def get_secret
  client = Aws::SecretsManager::Client.new(
    region: 'ap-northeast-1',
    access_key_id: '*************',
    secret_access_key: '************')

  begin
    get_secret_value_response = client.get_secret_value(secret_id: 'sample/demo/DBkey')
  rescue StandardError => e
    # For a list of exceptions thrown, see
    # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
    raise e
  end

  secret = get_secret_value_response.secret_string
  # Your code goes here.
end
```

`puts get_secret`してログを出してみます。
認証情報がログに出力されます。
```
rails_test-web-1  | Started GET "/" for 172.21.0.1 at 2024-07-10 18:22:58 +0000
rails_test-web-1  | Cannot render console from 172.21.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
rails_test-web-1  | Processing by UsersController#index as HTML
rails_test-web-1  | {"username":"*****","password":"***********","engine":"mysql","host":"***************************","port":3306,"dbInstanceIdentifier":"database-1"}
```

## 終わりに
実際に、Secrets Managerを使ってみました。
APIで認証情報を簡単に呼び出せるのでいろんな場面で使えそうです。
認証情報を定期的に更新しないといけない制約がある場合はこのサービスを使うと便利そうですね。

## 参考
https://qiita.com/hp-Genqiita/items/f93285a6058c64b39f23

https://zenn.dev/fdnsy/articles/133db8440d052f