はじめに
現在、下記のTwitter botを運用しています、これはTwitterのトレンド情報を定期的に取得、集計しその日最も呟かれていたトレンド情報をランキングにするものです。
https://twitter.com/BuzChecker
プログラムはPythonを使っておりAWS lambdaにデプロイし実行しています。
構成図はこんな感じ。
これは私がAWS初学者の頃に学習の過程で作ったもので色々とイケていない箇所がありAWSのベストプラクティスに沿った構成に改良したいというのが趣旨です。
改良後はこのようなイメージになります。
SecretsManagerを活用しよう
上記botのプログラムの実行にはTwitter、AWSの2種類の認証情報を必要としているのですが現在これらの認証情報であるアクセストークン、シークレットはプログラム内にハードコードされてしまっています。アクセストークン、シークレットをハードコードすることはこれらが漏洩してしまう危険性を孕んでいます。
AWSにはSecretsManagerというデータベースの認証情報、APIキー、その他の機密情報を管理、取得、ローテーションといったことを簡単かつ安全に実現できるサービスを提供しており、今回はSecretsManagerでアクセストークン、シークレットを管理しプログラム上にハードコードされている認証情報は削除します。
利用料金は1シークレットあたり$0.4/月 + 10,000回のAPIコールあたり$0.05かかります。
SecretsManagerに認証情報を登録する
これまで使用していた認証情報をSecretsManagerに登録していきます。
今回はその他のシークレットタイプを選択し、キー名に任意の名前、黒塗りしている箇所に各認証情報を入力します。
任意のシークレットの名前をつけます。今回はdev/twiTrend
としています。
今回はシークレットのローテーションは行わないため自動ローテーションの設定をオフにします。
ここまで設定を進めると最後に入力内容の確認画面が表示され一番下にシークレットを取得するサンプルコードを確認できます。
lambda関数にアタッチしているロールにSecretsManagerの使用を許可するポリシーをアタッチすることを忘れないようにしましょう。
SecretsManagerからシークレットを取得するようにコードを修正する
次にlambda関数のPythonでSecretsManagerからシークレットを取得するコードを追加します。
赤枠内のコードを追加し、ハードコードされていた認証情報と置き換えています。
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name="ap-northeast-1"
)
try:
get_secret_value_response = client.get_secret_value(
SecretId="dev/twiTrend"
)
except ClientError as e:
raise e
secret = json.loads(get_secret_value_response['SecretString'])
TW_CONSUMER_KEY = secret['TW_CONSUMER_KEY']
TW_CONSUMER_KEY_SECRET = secret['TW_CONSUMER_KEY_SECRET']
TW_ACCESS_TOKEN = secret['TW_ACCESS_TOKEN']
TW_ACCESS_TOKEN_SECRET = secret['TW_ACCESS_TOKEN_SECRET']
AWS_ACCESS_KEY = secret['AWS_ACCESS_KEY']
AWS_ACCESS_SECRET = secret['AWS_ACCESS_SECRET']