MomentoのトークンをAWS Secrets Manager経由で取得する

2022.07.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Introduction

この記事では、キャッシュサービスのMomentoを
Rustから使ってみました。
後半部分でAWS Lambdaから使っているのですが、
↑の書き方だとプログラムにMemontoのトークンが直接記述されています。
これはあまりよろしくなので、ここにあるように、
AWS Secrets Managerをつかって、トークンを取得するように修正します。

Environment

  • OS : MacOS 12.4
  • rust : 1.61.0

M1 Macで動かしました。
AWSアカウントはセットアップ済みとします。

また、以前の記事で作成した
momento-lambdaプロジェクトを元に解説します。

Use Momento with AWS Secrets Manager

momento-lambda/src/main.rsで直接Momentoのトークンを記述しているので、
AWS Secrets Managerで管理するように変更しましょう。

AWS Secrets Manager設定

コンソールでAWS Secrets Managerを開きます。

「新しいシークレットを保存する」を押し、「その他のシークレットのタイプ」を選択します。

キー/値のペアのところで、キーは「MOMENTO_AUTH_TOKEN」を記述。
値はMomentoのトークンを記述します。
次の画面へいき、名前に「accounts/MomentoAuthToken」を入力します。

シークレットローテーションを処理は設定せず、
最終確認をして保存します。
なお、ここで各言語のサンプルコードをみることができます。
(Rustはないですが)  

プログラム修正

次はプログラムの修正です。
ここを参考に実装していきましょう。

Cargo.tomlのdependenciesに必要なcrateを追加します。

aws-config = "0.15.0"
aws-sdk-secretsmanager = "0.15.0"
serde_json = "1.0.82"

そしてmain.rsの修正。
必要なライブラリのimportとさっき登録したシークレットの名前、
あとはSecrets Managerのリージョンを定義しておきます。

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_secretsmanager::{Client, Error as AwsError, Region, PKG_VERSION};
use serde_json::{Result as JsonResult, Value};

const MOMENTO_SECRET_ID: &str = "accounts/MomentoAuthToken";
const SECRET_REGION:&str ="ap-northeast-1";

そしてSecrets Managerからトークンを取得する関数と、
それを元にSimpleCacheClientを作成する関数を定義。
(エラー処理はかなり適当)

async fn init_client() -> Result<SimpleCacheClient,Error> {
    let auth_token = get_momento_auth_token().await?;
    let item_default_ttl_seconds = 60;
    return Ok(SimpleCacheClientBuilder::new(
        auth_token,
        NonZeroU64::new(item_default_ttl_seconds).unwrap(),
    )?.build());
}

async fn get_momento_auth_token() -> Result<String,Error> {
    let shared_config = aws_config::from_env().region(Region::new(SECRET_REGION)).load().await;
    let client = Client::new(&shared_config);
    
    let resp = client.get_secret_value().secret_id(MOMENTO_SECRET_ID).send().await?;
    let json = resp.secret_string().unwrap_or("No value!").to_string();
    let v: Value = serde_json::from_str(&json)?;
    return Ok(v["MOMENTO_AUTH_TOKEN"].as_str().unwrap().to_string() );
}

あとはfunction_handlerでinit_client関数を実行し、
Momentoのクライアントを取得します。

let mut cache_client = init_client().await?;

取得後の使い方は以前とまったく同じです。
これでトークンをプログラムに埋め込まず、
Momenotoへのアクセスを安全に行えるようになりました。