10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【初心者】AWS Secrets Manager と AWS Systems Manager Parameter Store を使ってみる

Posted at

1. 目的

  • AWSのセキュリティ関連サービスの復習をしている。パスワードなどの保護すべき値を安全に保存するための仕組みであるAWS Secrets Manager と AWS Systems Manager Parameter Store について、それぞれを試して使い勝手などを確認する。
  • 機能の差異や使い分けについては、Qiita記事「AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較」に詳しく整理、網羅されており、それを読むだけで一通り理解できるが、一応自分でどんなものか試してみる。

2. やったこと

  • RDSと、RDSへ接続し操作する用のEC2インスタンスを作成する。
  • RDSに接続する際のパスワードをそれぞれAWS Secrets Manager と AWS Systems Manager Parameter Storeに保存し、EC2インスタンスからの接続時に、値を呼び出して利用する。

3. 構成図

構成図.png

4. 設定手順

4.1 環境準備

[ec2-user@ip-10-0-0-196 ~]$ sudo yum install python3
[ec2-user@ip-10-0-0-196 ~]$ python3 -V
Python 3.7.9
[ec2-user@ip-10-0-0-196 ~]$ sudo pip3 install boto3
[ec2-user@ip-10-0-0-196 ~]$ sudo yum install python-devel mysql-devel
[ec2-user@ip-10-0-0-196 ~]$ sudo yum install python3-devel
[ec2-user@ip-10-0-0-128 ~]$ sudo yum install gcc
[ec2-user@ip-10-0-0-128 ~]$ sudo pip3 install mysqlclient
[ec2-user@ip-10-0-0-128 ~]$ sudo yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[ec2-user@ip-10-0-0-128 ~]$ sudo yum install -y mysql-community-client
  • RDS DBに接続し、テスト用のテーブルを作っておく。
[ec2-user@ip-10-0-0-128 ~]$ mysql -h mksamba-testdb-202103.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
mysql> create database mksambadb;
mysql> use mksambadb;
mysql> create table mksambadb.mytable(id int, stamp varchar(30));
mysql> insert into mytable (id, stamp)
    -> values('1', '1000');

4.2 EC2インスタンス(Python3)からの接続確認

  • RDSに接続するためのID/Passwordをコードにそのまま埋め込んで、RDSに接続できることを確認する。
dbconnect01.py
import MySQLdb

connection = MySQLdb.connect(
    host='mksamba-testdb-202103.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com',
    user='admin',
    passwd='PASSWORD',
    db='mksambadb')
cursor = connection.cursor()

cursor.execute("SELECT * FROM mksambadb.mytable")
for row in cursor:
    print(row)
connection.commit()
connection.close()
[ec2-user@ip-10-0-0-128 ~]$ python3 dbconnect01.py
(1, '1000')

4.3 Secret Manager の設定

  • Secret Manager にパスワードを保存する設定を行う。単純にパスワードのみを保存することもできるが、今回は「RDSデータベース認証情報」形式での保存を行う。
  • Secret Managerの画面にて、「新しいシークレットを保存する」を選択し、必要な項目を入力する。
    • シークレットの種類として、「RDSデータベースの認証情報」を選択する。
    • ユーザ名は「admin」、パスワードは設定したパスワード「PASSWORD」を入力する。
    • 暗号化キーとして、あらかじめ作成済のKMSカスタマーマスターキーを指定する。
    • このID/Passwordを使用して接続するRDS DBを選択する。

secret01a.png

  • このsecretの名前を「mksamba-secret-for-rds」とする。

secret02a.png

  • 今回はローテーションは無効のままにしておく。

secret03a.png

  • 最後に値を取得するためのサンプルコードが表示される。これをコピペして利用する。

secret04a.png

secret05a.png

4.4 Secret Manager からの値の取得

  • EC2インスタンスからRDS DBに接続する際に、パスワードをコードに埋め込むのではなく、Secret Managerに保存した値を取得して使用するように設定する。
  • EC2インスタンスに、Secret Manager及びKMSの権限があるIAM Roleを付与する。(今回は検証のため、Poweruser相当の権限を付与)
  • コードは以下のように修正する。注意点として、Secret(ID/Passwordの値を保存)が文字列型のため、辞書型に変更した上で値を取得する。DevelopersIOの記事「PythonでAWS Secrets ManagerからAPIキーを取得するときのちょっとしたポイント」のやり方を利用させて頂いた。
dbconnect02.py
import MySQLdb
import boto3
import base64
from botocore.exceptions import ClientError
import ast

secret_name = "mksamba-secret-for-rds"
region_name = "ap-northeast-1"

session = boto3.session.Session()
client = session.client(
    service_name='secretsmanager',
    region_name=region_name
)

try:
     get_secret_value_response = client.get_secret_value(
        SecretId=secret_name
    )
except ClientError as e:
    if e.response['Error']['Code'] == 'DecryptionFailureException':
        raise e
    elif e.response['Error']['Code'] == 'InternalServiceErrorException':
        raise e
    elif e.response['Error']['Code'] == 'InvalidParameterException':
        raise e
    elif e.response['Error']['Code'] == 'InvalidRequestException':
        raise e
    elif e.response['Error']['Code'] == 'ResourceNotFoundException':
        raise e
else:
    if 'SecretString' in get_secret_value_response:
        secret = get_secret_value_response['SecretString']
    else:
        decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])

secret = ast.literal_eval(secret)

connection = MySQLdb.connect(
    host='mksamba-testdb-202103.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com',
    user=secret['username'],
    passwd=secret['password'],
    db='mksambadb')
cursor = connection.cursor()

cursor.execute("SELECT * FROM mksambadb.mytable")
for row in cursor:
    print(row)
connection.commit()
connection.close()

4.5 Parameter Store の設定

  • 今度はパスワードの値をParameter Storeに保存してみる。
  • AWS Systems Managerの画面にて、「パラメータストア」- 「パラメータを作成」を選択する。
    • タイプは「安全な文字列」を選択し、暗号化を行う。
    • あらかじめ作成済のKMS カスタマーマスターキーを指定する。
    • 値として、パスワードの文字列「PASSWORD」を入力する。

secret06a.png

4.6 Parameter Store からの値の取得

  • EC2インスタンスからRDS DBに接続する際に、パスワードをコードに埋め込むのではなく、Parameter Storeに保存した値を取得して使用するように設定する。
  • EC2インスタンスに、Systems Manager及びKMSの権限があるIAM Roleを付与する。(今回は検証のため、Poweruser相当の権限を付与)
  • コードは以下のように修正する。手順はDevelopersIO記事「AWS SDK for Python (Boto3) で AWS Systems Manager パラメータストアから情報を取得する」を参照。
dbconnect03.py
import MySQLdb
import boto3
import json

ssm = boto3.client('ssm', 'ap-northeast-1')
response = ssm.get_parameters(
    Names=[
        'mksamba-password-rds',
    ],
    WithDecryption=True
)

connection = MySQLdb.connect(
    host='mksamba-testdb-202103.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com',
    user='admin',
    passwd=response['Parameters'][0]['Value'],
    db='mksambadb')
cursor = connection.cursor()

cursor.execute("SELECT * FROM mksambadb.mytable")
for row in cursor:
    print(row)
connection.commit()
connection.close()

5. 所感

  • どちらも隠したい値を暗号化して保存しておき、必要な時に取り出して使用する、という点ではそんなに変わりなく使えるかなと思った。費用や、細かい機能の差異(Secret Managerの値の自動更新機能など)の必要性に応じて判断できるようにしたい。
10
6
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
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?