Terraformで作成した「ElastiCache for Redis」の認証トークンをどう管理するか

Posted on
AWS Redis

TerraformでElastiCache for Redisを構築する時の認証トークンの管理方法について書きます。

Terraformを使ってElastiCache for Redisを作成した時に「認証トークンをどう管理するか?」という課題があります。 素でTerraformのコードを書くとauth_tokenというパラメータに認証トークンを渡す必要があります。 これをやってしまうとTerraformのstateファイルに認証トークンが暗号化されていない状態で残ってしまいセキュアとは言えません。 もう一つの方法としてSSMにSecureStringパラメータとして認証トークンを保存しておきdataを使って取得する、という方法があります。 これはこれでいいのですが、Terraformのコードが若干複雑になってしまいます。

実はre:Invent 2019でElastiCache for Redisの認証トークンの動的な変更がサポートされました。 これにより、シンプルに認証トークンを管理することができるようになりました。

認証トークンの管理方法

以下の方法で認証トークンを管理します。

  • 認証トークンをdummy値にセットしてクラスターを作成する(stateにはdummy値が記録される)
  • AWS CLI経由で認証トークンを変更する
  • 変更した認証トークンはパスワードマネージャで管理する

メリット

この方法では以下のメリットがあります。

  • Terraformのstateに認証トークンが残らない(セキュア)
  • SSMのSecureStringを用いる方法よりもTerraformのコードが短くなる(シンプル)

実際に試してみる

Terraformを使ってこの方法を試してみます

terraformでRedisを作成する

  • まずはTerraformのコードを書きます
    • 認証トークン(auth_token)はダミー値を設定しておきます
resource "aws_elasticache_replication_group" "sample_redis" {
  replication_group_id          = "sample-redis"
  replication_group_description = "sample-redis"
  engine                        = "redis"
  engine_version                = "5.0.6"
  subnet_group_name             = aws_elasticache_subnet_group.sample_redis.name
  node_type                     = "cache.m5.large"
  port                          = "6379"
  parameter_group_name          = "default.redis5.0"
  automatic_failover_enabled    = true

  security_group_ids         = [aws_security_group.sample_redis.id]
  snapshot_retention_limit   = 1
  transit_encryption_enabled = true
  at_rest_encryption_enabled = true
  # tf apply 時にはdummy valueで登録した上で認証トークンを変更する
  # 秘匿情報をtfstateに残さないようにするため
  auth_token            = "dummydummydummydummy"
  number_cache_clusters = 2
}
  • terraform applyします
  • クラスタのステータスを確認します
> aws elasticache describe-cache-clusters --cache-cluster-id sample-redis-001 | jq '.CacheClusters[].CacheClusterStatus'
"available"

認証トークンとして用いる値を生成

  • パスワード生成ツールを用いて認証トークンとして用いる値を生成します
    • 認証トークンとして利用可能な文字列にはルールがあります
    • 詳しくは公式ドキュメントを参照ください

認証トークンを変更

  • 前述のとおり、認証トークンを(クラスタを再作成することなく)変更することができます
    • 前提として「エンジンバージョンが5.0.5以上」かつ「TLSが有効化」されている必要があります
  • 認証トークンの変更についてはROTATESETというStrategyがあります
    • ROTATE:以前の認証トークンを保持しながら、サーバに別の認証トークンを追加する
    • SET:単一の認証トークンをサポートするように設定を変更する
  • 先ほど作成した認証トークンのみで認証できるようにするためにROTATE->SETの順にコマンドを実行します
aws elasticache modify-replication-group \
--replication-group-id sample-redis \
--auth-token <auth_token> \
--auth-token-update-strategy ROTATE \
--apply-immediately
aws elasticache modify-replication-group \
--replication-group-id sample-redis \
--auth-token <auth_token> \
--auth-token-update-strategy SET \
--apply-immediately

パスワードマネージャに保存

  • パスワードマネージャに保存します
  • この認証トークンをアプリケーションから使います

まとめ

認証トークンをクラスター作成後に動的に変更する機能がサポートされたことで、ElastiCache for Redisの認証トークンをセキュアに運用することができるようになりました。Terraformのコードをシンプルに保つこともできますし、ベターな運用だと考えています。