これは、なにをしたくて書いたもの?
Severless Frameworkのserverless.yml
でAWS Systems Manager Parameter Storeの値を参照できるみたいなので、試してみることに
しました。
合わせて、AWS Lambda関数内からAWS Systems Manager Parameter Storeを参照するようにもしてみましょう。
Serverless Frameworkの設定ファイルからAWS Systems Manager Parameter Storeの値を参照する
Serverless Frameworkの設定ファイル(serverless.yml
)からAWS Systems Manager Parameter Storeの値を参照する方法は、
以下に記載があります。
Variables / Reference Variables using the SSM Parameter Store
こんな感じで${ssm:[パラメーター名]}
で参照します。
service: ${ssm:/path/to/service/id}-service provider: name: aws functions: hello: name: ${ssm:/path/to/service/myParam}-hello handler: handler.hello
指定したデータの型がSecureString
やStringList
のようなものの場合は、自動的に展開されるようです。
SecureString
であれば自動で復号され、その挙動を抑制することもできるようです。
Variables / Reference Variables using the SSM Parameter Store / Resolution of non plain string types
今回は扱いませんが、AWS Secrets Managerから値を参照することもできるようです。指定方法は${ssm:〜}
となっており、
AWS Systems Manager Parameter Storeを使う時と同じようです。
Variables / Reference Variables using AWS Secrets Manager
AWS CloudFormationでも同様にAWS Systems Manager Parameter StoreやAWS Secrets Managerから値を参照することができます。
動的な参照を使用してテンプレート値を指定する - AWS CloudFormation
AWS CloudFormationの場合はAWS Systems Managerの値を参照する場合はssm
やssm-secure
、AWS Secrets Managerの場合は
secretsmanager
と使い分けが必要なようです。
説明はこれくらいにして、実際に使っていってみましょう。
言語はNode.js+TypeScript、環境はLocalStackを使います。AWS Systems Manager Parameter Storeに格納する情報として、
データベースアクセスも含めることにしましょう。こちらにはMySQLを使用します。
環境
今回の環境は、こちらです。
LocalStack。
$ python3 -V Python 3.10.6 $ localstack --version 2.1.0
起動。
$ LAMBDA_EXECUTOR=docker-reuse localstack start
$ awslocal --version aws-cli/2.12.3 Python/3.11.4 Linux/5.15.0-75-generic exe/x86_64.ubuntu.22 prompt/off
Terraform。Serverless Framework管理外のものは、Terraformで構築することにします。
$ terraform version Terraform v1.5.1 on linux_amd64
MySQL localhost:3306 ssl SQL > select version(); +-----------+ | version() | +-----------+ | 8.0.33 | +-----------+ 1 row in set (0.0002 sec)
MySQLは172.17.0.3で動作しているものとします。
Terraformで環境を構築する
まずはTerraformで環境を構築していきます。
AWS Lambda関数ではAmazon SNSをサブスクライブすることにして、このトピックを作成することにします。
それからMySQLのデータベースやユーザーもTerraformで作成し、Amazon SNSのARNやMySQLへの接続情報を
AWS Systems Manager Parameter Storeに格納することにしましょう。
つまり、こういうTerraform構成ファイルを作成しました。
main.tf
terraform { required_version = "1.5.1" required_providers { aws = { source = "hashicorp/aws" version = "5.5.0" } mysql = { source = "bangau1/mysql" version = "1.10.4" } } } provider "aws" { access_key = "mock_access_key" region = "us-east-1" secret_key = "mock_secret_key" skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true endpoints { sns = "http://localhost:4566" ssm = "http://localhost:4566" } } provider "mysql" { endpoint = "172.17.0.3:3306" username = "root" password = "password" } resource "mysql_database" "practice" { name = "practice" default_character_set = "utf8mb4" default_collation = "utf8mb4_0900_bin" } resource "mysql_user" "user" { user = "kazuhira" host = "%" plaintext_password = "password" } resource "mysql_grant" "grant" { user = mysql_user.user.user host = mysql_user.user.host database = mysql_database.practice.name privileges = ["ALL PRIVILEGES"] } resource "aws_sns_topic" "my_topic" { name = "my-topic" } resource "aws_ssm_parameter" "my_topic_arn" { name = "my-topic-arn" type = "SecureString" value = aws_sns_topic.my_topic.arn } resource "aws_ssm_parameter" "mysql_host" { name = "mysql-host" type = "SecureString" value = "172.17.0.3" } resource "aws_ssm_parameter" "mysql_port" { name = "mysql-port" type = "SecureString" value = "3306" } resource "aws_ssm_parameter" "mysql_database" { name = "mysql-database" type = "SecureString" value = mysql_database.practice.name } resource "aws_ssm_parameter" "mysql_user" { name = "mysql-user" type = "SecureString" value = mysql_user.user.user } resource "aws_ssm_parameter" "mysql_password" { name = "mysql-password" type = "SecureString" value = "password" }
terraform init
して、terraform apply
して構築完了。
$ terraform init $ terraform apply
確認。
$ awslocal ssm describe-parameters --query Parameters[].Name [ "mysql-password", "mysql-port", "mysql-database", "mysql-host", "mysql-user", "my-topic-arn" ]
Serverless Frameworkを使ってAWS Lambda関数を作成する
続いては、Serverless Frameworkを使ってAWS Lambda関数を作成していきます。
Node.jsプロジェクトを作成し、TypeScriptやServerless Frameworkを依存関係に追加
$ npm init -y $ npm i -D typescript $ npm i -D serverless
aws-nodejs
テンプレートを使って、サービスを作成。
$ npx serverless create --template aws-nodejs
Serverless Framework Commands - AWS Lambda - Create
生成されたserverless.yml
とAWS Lambda関数。
serverless.yml
# Welcome to Serverless! # # This file is the main config file for your service. # It's very minimal at this point and uses default values. # You can always add more config options for more control. # We've included some commented out config examples here. # Just uncomment any of them to get that config option. # # For full config options, check the docs: # docs.serverless.com # # Happy Coding! service: serverless-ssm-parameter-store # app and org for use with dashboard.serverless.com #app: your-app-name #org: your-org-name # You can pin your service to only deploy with a specific Serverless version # Check out our docs for more details frameworkVersion: "3" provider: name: aws runtime: nodejs18.x # you can overwrite defaults here # stage: dev # region: us-east-1 # you can add statements to the Lambda function's IAM Role here # iam: # role: # statements: # - Effect: "Allow" # Action: # - "s3:ListBucket" # Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } # - Effect: "Allow" # Action: # - "s3:PutObject" # Resource: # Fn::Join: # - "" # - - "arn:aws:s3:::" # - "Ref" : "ServerlessDeploymentBucket" # - "/*" # you can define service wide environment variables here # environment: # variable1: value1 # you can add packaging information here #package: # patterns: # - '!exclude-me.js' # - '!exclude-me-dir/**' # - include-me.js # - include-me-dir/** functions: hello: handler: handler.hello # The following are a few example events you can configure # NOTE: Please make sure to change your handler code to work with those events # Check the event documentation for details # events: # - httpApi: # path: /users/create # method: get # - websocket: $connect # - s3: ${env:BUCKET} # - schedule: rate(10 minutes) # - sns: greeter-topic # - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 # - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx # - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx # - iot: # sql: "SELECT * FROM 'some_topic'" # - cloudwatchEvent: # event: # source: # - "aws.ec2" # detail-type: # - "EC2 Instance State-change Notification" # detail: # state: # - pending # - cloudwatchLog: '/aws/lambda/hello' # - cognitoUserPool: # pool: MyUserPool # trigger: PreSignUp # - alb: # listenerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:listener/app/my-load-balancer/50dc6c495c0c9188/ # priority: 1 # conditions: # host: example.com # path: /hello # Define function environment variables here # environment: # variable2: value2 # you can add CloudFormation resource templates here #resources: # Resources: # NewResource: # Type: AWS::S3::Bucket # Properties: # BucketName: my-new-bucket # Outputs: # NewOutput: # Description: "Description for the output" # Value: "Some output value"
handler.js
'use strict'; module.exports.hello = async (event) => { return { statusCode: 200, body: JSON.stringify( { message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }, null, 2 ), }; // Use this code if you don't use the http event with the LAMBDA-PROXY integration // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; };
AWS Lambda関数の雛形は、不要なので削除しておきます。
$ rm handler.js
続いて、Prettierや型宣言を追加。
$ npm i -D prettier $ npm i -D @types/node@v18 $ npm i -D @types/aws-lambda
Serverless Frameworkのesbuildプラグインや、LocalStack向けのプラグインも追加。
$ npm i -D serverless-esbuild esbuild $ npm i -D serverless-localstack
AWS Systems Manager Parameter StoreにアクセスするためにSSMClient
を追加し、MySQLにアクセスするためにmysql2
も
加えます。
$ npm i @aws-sdk/client-ssm $ npm i mysql2
あとはテスト用にJest、esbuild-jestを追加。
$ npm i -D jest @types/jest $ npm i -D esbuild-jest
各種設定ファイルも載せておきます。
依存関係。
"devDependencies": { "@types/aws-lambda": "^8.10.119", "@types/jest": "^29.5.2", "@types/node": "^18.16.18", "esbuild": "^0.17.19", "esbuild-jest": "^0.5.0", "jest": "^29.5.0", "prettier": "^2.8.8", "serverless": "^3.32.2", "serverless-esbuild": "^1.45.1", "serverless-localstack": "^1.1.1", "typescript": "^5.1.3" }, "dependencies": { "@aws-sdk/client-ssm": "^3.359.0", "mysql2": "^3.4.1" }
scripts
。
"scripts": { "typecheck": "tsc --project .", "typecheck:watch": "tsc --project . --watch", "test": "jest", "format": "prettier --write ./**/*.{js,ts}" },
tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "commonjs", "moduleResolution": "node", "lib": ["esnext"], "noEmit": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, "noPropertyAccessFromIndexSignature": true, "esModuleInterop": true }, "include": ["./**/*.ts"], "exclude": [ "node_modules/**/*", ".serverless/**/*" ] }
tsconfig.typecheck.json
{ "extends": "./tsconfig", "compilerOptions": { "baseUrl": "./", "noEmit": true } }
.prettierrc.json
{ "singleQuote": true, "printWidth": 120 }
jest.config.js
module.exports = { testEnvironment: 'node', transform: { '^.+\\.tsx?$': 'esbuild-jest', }, };
作成したAWS Lambda関数。
subscribe-sns/handler.ts
import { GetParameterCommand, GetParameterCommandInput, SSMClient } from '@aws-sdk/client-ssm'; import { SNSEvent } from 'aws-lambda'; import { randomUUID } from 'crypto'; import mysql from 'mysql2/promise'; function getSsmEndpoint(): string { if (process.env['LOCALSTACK_HOSTNAME'] !== undefined) { return `http://${process.env['LOCALSTACK_HOSTNAME']}:4566`; } else { return 'http://localhost:4566'; } } const ssmClient = new SSMClient({ credentials: { accessKeyId: 'test', secretAccessKey: 'test', }, region: 'us-east-1', endpoint: getSsmEndpoint(), }); async function getParameter(name: string): Promise<string> { const input: GetParameterCommandInput = { Name: name, WithDecryption: true, }; const output = await ssmClient.send(new GetParameterCommand(input)); return output.Parameter?.Value!; } export const handler = async (event: SNSEvent): Promise<void> => { const connection = await mysql.createConnection({ host: await getParameter('mysql-host'), port: parseInt(await getParameter('mysql-port'), 10), database: await getParameter('mysql-database'), user: await getParameter('mysql-user'), password: await getParameter('mysql-password'), }); try { await connection.execute(` create table if not exists subscribe_log( id varchar(36), message_id varchar(36), message text, registered_datetime datetime, primary key(id) ) `); await connection.beginTransaction(); for (const record of event.Records) { await connection.query( ` insert into subscribe_log(id, message_id, message, registered_datetime) values(?, ?, ?, now()) `, [randomUUID(), record.Sns.MessageId, record.Sns.Message] ); console.info( `[${new Date().toISOString()}] messageId = [${record.Sns.MessageId}], message = [${record.Sns.Message}]` ); } await connection.commit(); } catch (e) { await connection.rollback(); console.log(e); } finally { await connection.end(); } };
Amazon SNSをサブスクライブして、メッセージなどをMySQLへ保存するAWS Lambda関数です。保存先のテーブルは、実行時に
存在していなければ作成します。
MySQLへの接続情報は、AWS Systems Manager Parameter Storeから取得するようにしています。
function getSsmEndpoint(): string { if (process.env['LOCALSTACK_HOSTNAME'] !== undefined) { return `http://${process.env['LOCALSTACK_HOSTNAME']}:4566`; } else { return 'http://localhost:4566'; } } const ssmClient = new SSMClient({ credentials: { accessKeyId: 'test', secretAccessKey: 'test', }, region: 'us-east-1', endpoint: getSsmEndpoint(), }); async function getParameter(name: string): Promise<string> { const input: GetParameterCommandInput = { Name: name, WithDecryption: true, }; const output = await ssmClient.send(new GetParameterCommand(input)); return output.Parameter?.Value!; } export const handler = async (event: SNSEvent): Promise<void> => { const connection = await mysql.createConnection({ host: await getParameter('mysql-host'), port: parseInt(await getParameter('mysql-port'), 10), database: await getParameter('mysql-database'), user: await getParameter('mysql-user'), password: await getParameter('mysql-password'), });
エンドポイントは、LocalStack内で動作させている時は環境変数LOCALSTACK_HOSTNAME
を参照するようにして、それ以外は
LocalStackへlocalhost
でアクセスできるものとして指定します。
Serverless Framworkの設定ファイル。
serverless.yml
service: serverless-ssm-parameter-store frameworkVersion: "3" provider: name: aws runtime: nodejs18.x stage: dev region: us-east-1 package: individually: true functions: subscribeSns: handler: subscribe-sns/handler.handler events: - sns: ${ssm:my-topic-arn} custom: esbuild: bundle: true target: node18 platform: node plugins: - serverless-esbuild - serverless-localstack
Amazon SNSのARNは、AWS Systems Manager Parameter Storeから取得するようにしています。
functions: subscribeSns: handler: subscribe-sns/handler.handler events: - sns: ${ssm:my-topic-arn}
すでに存在するAmazon SNSトピックをサブスクライブするには、ARNを指定すればよさそうなので。
SNS / Using a pre-existing topic
デプロイ。
$ npx serverless deploy
$ TOPIC_ARN=$(awslocal sns list-topics --query Topics[0].TopicArn --output text) $ awslocal sns publish --topic-arn $TOPIC_ARN --message 'test' { "MessageId": "8db1b998-edcb-4842-ad9b-ac3c00e805d6" }
ログを確認。
$ awslocal logs tail /aws/lambda/serverless-ssm-parameter-store-dev-subscribeSns 2023-06-28T15:08:34.035000+00:00 2023/06/28/[$LATEST]1c7fb102c5cf2e155b632cf2550a65a4 START RequestId: dce667e0-67ff-4219-b996-2eaca751a07a Version: $LATEST 2023-06-28T15:08:34.042000+00:00 2023/06/28/[$LATEST]1c7fb102c5cf2e155b632cf2550a65a4 2023-06-28T15:08:33.997Z dce667e0-67ff-4219-b996-2eaca751a07a INFO [2023-06-28T15:08:33.996Z] messageId = [8db1b998-edcb-4842-ad9b-ac3c00e805d6], message = [test] 2023-06-28T15:08:34.049000+00:00 2023/06/28/[$LATEST]1c7fb102c5cf2e155b632cf2550a65a4 END RequestId: dce667e0-67ff-4219-b996-2eaca751a07a 2023-06-28T15:08:34.056000+00:00 2023/06/28/[$LATEST]1c7fb102c5cf2e155b632cf2550a65a4 REPORT RequestId: dce667e0-67ff-4219-b996-2eaca751a07a Duration: 466.38 ms Billed Duration: 467 ms Memory Size: 1024 MB Max Memory Used: 1024 MB
動作していますね。
MySQL側も確認してみましょう。
MySQL localhost:3306 ssl practice SQL > select * from subscribe_log; +--------------------------------------+--------------------------------------+---------+---------------------+ | id | message_id | message | registered_datetime | +--------------------------------------+--------------------------------------+---------+---------------------+ | 9d35aecd-ffed-4c3c-a0a9-7bc49e295f2f | 8db1b998-edcb-4842-ad9b-ac3c00e805d6 | test | 2023-06-28 15:08:33 | +--------------------------------------+--------------------------------------+---------+---------------------+ 1 row in set (0.0011 sec)
こちらもOKですね。
というわけで、AWS Systems Manager Parameter Storeに格納した値をserverless.yml
で参照できることを確認できました。
ついでに、AWS Lambda関数内からAWS Systems Manager Parameter Storeへもアクセスしておいたわけですが。
serverless generate-event
も使ってみましょう。
ローカル呼び出し確認。
$ npx serverless generate-event -t aws:sns -b 'Hello Serverless generate-event and invoke local' | npx serverless invoke local --function subscribeSns Using serverless-localstack serverless-localstack: Reconfigured endpoints [2023-06-28T15:13:00.228Z] messageId = [52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a], message = [Hello Serverless generate-event and invoke local]
デプロイした関数の呼び出し。
$ npx serverless generate-event -t aws:sns -b 'Hello Serverless generate-event and invoke' | npx serverless invoke --function subscribeSns Using serverless-localstack serverless-localstack: Reconfigured endpoints null
データは両方とも入っています。
MySQL localhost:3306 ssl practice SQL > select * from subscribe_log; +--------------------------------------+--------------------------------------+--------------------------------------------------+---------------------+ | id | message_id | message | registered_datetime | +--------------------------------------+--------------------------------------+--------------------------------------------------+---------------------+ | 5dfafd57-f8ce-413c-9a12-4e6cc2dd0c3a | 52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a | Hello Serverless generate-event and invoke | 2023-06-28 15:13:45 | | 9d35aecd-ffed-4c3c-a0a9-7bc49e295f2f | 8db1b998-edcb-4842-ad9b-ac3c00e805d6 | test | 2023-06-28 15:08:33 | | aa817921-0053-4970-aece-57788fad47a7 | 52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a | Hello Serverless generate-event and invoke local | 2023-06-28 15:13:00 | +--------------------------------------+--------------------------------------+--------------------------------------------------+---------------------+ 3 rows in set (0.0009 sec)
テストを書く
オマケ的に、最後にテストを書いてみましょう。
以下でテストデータを作成。
$ npx serverless generate-event -t aws:sns -b '{"message": "Hello World!!"}' | jq { "Records": [ { "EventSource": "aws:sns", "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789:service-1474781718017-1:fdaa4474-f0ff-4777-b1c4-79b96f5a504f", "Sns": { "Type": "Notification", "MessageId": "52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a", "TopicArn": "arn:aws:sns:us-east-1:123456789:service-1474781718017-1", "Subject": "", "Message": "{\"message\": \"Hello World!!\"}", "Timestamp": "2016-09-25T05:37:51.150Z", "SignatureVersion": "1", "Signature": "V5QL/dhow62Thr9PXYsoHA7bOsDFkLdWZVd8D6LyptA6mrq0Mvldvj/XNtai3VaPp84G3bD2nQbiuwYbYpu9u9uHZ3PFMAxIcugV0dkOGWmYgKxSjPApItIoAgZyeH0HzcXHPEUXXO5dVT987jZ4eelD4hYLqBwgulSsECO9UDCdCS0frexiBHRGoLbWpX+2Nf2AJAL+olEEAAgxfiPEJ6J1ArzfvTFZXdd4XLAbrQe+4OeYD2dw39GBzGXQZemWDKf4d52kk+SwXY1ngaR4UfExQ10lDpKyfBVkSwroaq0pzbWFaxT2xrKIr4sk2s78BsPk0NBi55xA4k1E4tr9Pg==", "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a0e6b3aafc7f4149a.pem", "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789:service-1474781718017-1:fdaa4474-f0ff-4777-b1c4-79b96f5a504f", "MessageAttributes": {} } } ] }
こちらを少し加工して、テストでのAWS Lambda関数の呼び出し時のメッセージにします。
subscribe-sns/handler.test.ts
import { SNSEvent } from 'aws-lambda'; import { handler } from './handler'; import mysql from 'mysql2/promise'; import { Connection } from 'mysql2/promise'; let connection: Connection; beforeAll(async () => { connection = await mysql.createConnection({ host: '172.17.0.3', port: 3306, database: 'practice', user: 'kazuhira', password: 'password', }); }); afterAll(async () => { await connection.end(); }); beforeEach(async () => { const [rows] = await connection.query( ` select count(1) as count from information_schema.tables where table_schema = ? and table_name = ? `, ['practice', 'subscribe_log'] ); if ((rows as any[])[0].count > 0) { await connection.query(`truncate table subscribe_log`); } }); test('subscribe SNS event', async () => { const payload: SNSEvent = JSON.parse(` { "Records": [ { "EventSource": "aws:sns", "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789:service-1474781718017-1:fdaa4474-f0ff-4777-b1c4-79b96f5a504f", "Sns": { "Type": "Notification", "MessageId": "52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a", "TopicArn": "arn:aws:sns:us-east-1:123456789:service-1474781718017-1", "Subject": "", "Message": "{\\"message\\": \\"Hello World!!\\"}", "Timestamp": "2016-09-25T05:37:51.150Z", "SignatureVersion": "1", "Signature": "V5QL/dhow62Thr9PXYsoHA7bOsDFkLdWZVd8D6LyptA6mrq0Mvldvj/XNtai3VaPp84G3bD2nQbiuwYbYpu9u9uHZ3PFMAxIcugV0dkOGWmYgKxSjPApItIoAgZyeH0HzcXHPEUXXO5dVT987jZ4eelD4hYLqBwgulSsECO9UDCdCS0frexiBHRGoLbWpX+2Nf2AJAL+olEEAAgxfiPEJ6J1ArzfvTFZXdd4XLAbrQe+4OeYD2dw39GBzGXQZemWDKf4d52kk+SwXY1ngaR4UfExQ10lDpKyfBVkSwroaq0pzbWFaxT2xrKIr4sk2s78BsPk0NBi55xA4k1E4tr9Pg==", "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a0e6b3aafc7f4149a.pem", "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789:service-1474781718017-1:fdaa4474-f0ff-4777-b1c4-79b96f5a504f", "MessageAttributes": {} } } ] } `) as SNSEvent; await handler(payload); const [counts] = await connection.query('select count(1) as count from subscribe_log'); expect(counts).toStrictEqual([{ count: 1 }]); const [rows] = await connection.query(`select id, message_id, message, registered_datetime from subscribe_log`); expect(rows).toHaveLength(1); expect((rows as any[])[0]).toHaveProperty('message', '{"message": "Hello World!!"}'); });
データは、テストごとにtruncate table
するようにしています。
確認。
$ npm run test > serverless-ssm-parameter-store@1.0.0 test > jest console.info [2023-06-28T15:17:04.959Z] messageId = [52ed5e3d-5fgf-56bf-923d-0e5c3b503c2a], message = [{"message": "Hello World!!"}] at handler (subscribe-sns/handler.ts:88:15) PASS subscribe-sns/handler.test.ts ✓ subscribe SNS event (524 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.291 s, estimated 2 s Ran all test suites.
まとめ
Serverless Frameworkで、AWS Systems Manager Parameter Storeから値を参照するようにしてみました。
割とあっさり使えて便利ですね。AWS Lambda関数でこういうハードコードしたくない値かつ簡単に見えないようにしたい値の管理には
こうやってserverless.yml
で参照するか、AWS Lambda関数内の処理そのもので参照することになると思うので、押さえておこうと
思います。