SSMのパラメータストアを活用して Lambda で機密情報 (SecureString) を扱う with AWS SAM
Slackにメッセージを通知するLambdaを作っていると、Webhook URLの扱いに困ります。
ソースコード内にべた書きしたくないので、デプロイ時に環境変数として与えていました。
この運用もめんどくさいと感じていたところ、「SSMのパラメータストアを使えばいいんじゃね?」となったので、試してみました。
おすすめの方
- Lambdaでパラメータストア(安全な文字列)を使いたい
- AWS SAMでパラメータストア(安全な文字列)を使いたい
目次
環境
項目 | バージョン |
---|---|
macOS | Mojave 10.14.5 |
AWS CLI | aws-cli/1.16.174 Python/3.6.1 Darwin/18.6.0 botocore/1.12.164 |
AWS SAM CLI | 0.17.0 |
Python | 3.6 |
AWS SAMのサーバーレスアプリケーションを用意する
下記のサーバーレスアプリケーションを流用します。
- 電車の運行情報(遅延・運転見合・運休など)を毎朝Slackに通知してみた | Developers.IO
- Slackで「今の電車の運行情報」を自分だけに教えてくれるSlash commandsを作った | Developers.IO
今のWebhook URLの扱い
template.yaml
でLambdaの環境変数として定義しています。
Parameters: SlackWebhookUrl: Type: String Default: hoge Resources: NotifyPeriodicFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: periodic.lambda_handler Runtime: python3.6 Environment: Variables: # このURLはコミット&公開したくないため、デプロイ時にコマンドで設定する SLACK_WEBHOOK_URL: !Ref SlackWebhookUrl Events: NotifySlack: Type: Schedule Properties: Schedule: cron(1/10 23 * * ? *) # 日本時間AM8時1分から10分毎に毎日通知する
環境変数の値は、デプロイ時にparameter-overrides
オプションで渡しています。
sam deploy \ --template-file packaged.yaml \ --stack-name NotifyTrainDelayToSlack \ --capabilities CAPABILITY_IAM \ --parameter-overrides SlackWebhookUrl=https://hooks.slack.com/services/xxxxxxxxxxxxx
これをパラメータストアの利用に置き換えます!
パラメータストアを利用する
AWS側の設定
System Managerにアクセスします。
左側メニューの最下部にある「パラメータストア」を選択します。
「パラメータストアの作成」を選択します。
いろいろと入力します。
項目 | 内容 |
---|---|
名前 | NotifyTrainDelayToSlack-WebhookURL |
説明 | 適当に入力 |
利用枠 | 標準 |
タイプ | 安全な文字列 |
KMS の主要なソース | 現在のアカウント |
値 | 実際のWebhookURL |
入力後、右下の「パラメータの作成」を選択します。
パラメータストアにWebhookURLを保存する作業は、以上で完了です!
SAMテンプレートの修正
変更点は下記です。
- Lambdaの環境変数をバッサリ削除する
- SecureStringは、CloudFormationで未サポートのため
AmazonSSMReadOnlyAccess
のポリシーを明示的に定義する
Resources: NotifyPeriodicFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: periodic.lambda_handler Runtime: python3.6 Policies: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess Events: NotifySlack: Type: Schedule Properties: Schedule: cron(1/10 23 * * ? *) # 日本時間AM8時1分から10分毎に毎日通知する
Lambdaコードの修正
下記のようにして、パラメータストアからWebhookURLを取得します。
import boto3 ssm = boto3.client('ssm') def get_notify_url() -> str: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter response = ssm.get_parameter( Name='NotifyTrainDelayToSlack-WebhookURL', WithDecryption=True ) return response['Parameter']['Value']
動作確認
Lambdaを手動実行させます。
無事に通知されました!!
Slashコマンドによる通知も問題なしです。
さいごに
サクッと使えるのがありがたいですね。
全体のコードはGitHubにあります。