【初心者向け】AWS CDKを使ってAmazon SNSをデプロイしてみた!

2021.12.06

こんにちは、CX事業本部 IoT事業部のアベシ(阿部)です!

最近初めてAWS CDKを触り、実際にAWSリソースをデプロイしてみました。 最初の取り組みとしてAmazon SNSのリソースを作成し通知を実際に送ってみましたので、CDKを使うために必要なセットアップ内容や、リソースの構築までに行った手順等をブログに残したいと思います。

※内容は初心者様向けです。私自身も知識が足りていないところが多いかと思いますので、気になる点があればコメント等でご指摘頂けますと幸いです。

AWS CDK

CDKとは?

TypeScriptなどのプログラミング言語でAWSリソースを定義でき、定義した内容に基づいてCloudFotmaitonを生成、AWSへリソースをデプロイできます。これらの過程はAWS CLIをインストールした上でコマンド操作によりすべて実行可能です。普段使い慣れた言語でリソースの定義しコマンド操作でCloudFormationが生成できることや、CloudFormationで記述するよりもコード量を減らせるメリットがあります。以下のドキュメントが導入部分から非常にわかりやすく記載されてましたので是非参考にしていただければ思います。

使うための環境準備

CDKを一から使うための環境の準備は、先程紹介したドキュメントと併用して下にリンクを貼ったAWS公式のワークショップの内容も参考に行いました。TypeScript , Python , C#/.NET , Javaを使う場合の方法が網羅されております。

各言語の共通したセットアップ事項は以下となります。

  • AWS CLI をインストール
  • aws configureコマンドでデプロイ先のAWSアカウント情報をターミナルに入力
  • NODE.JSのインストール
  • AWS CDK Toolkitをインストール
  • CDKでのデプロイが初回の場合はcdk bootstrapコマンドを実行します。これによりCloudFromationテンプレートが保存されるS3バケットなどがAWSにデプロイされます。

Amazon SNSとは?

Amazon Simple Notification Service (SNS) はメッセージ通知のインフラを提供するフルマネージドサービスです。大きく2つの使い方があります。

・アプリケーションからアプリケーションへの通知(A2A)

Amazon SNSからLambda等のサービスにメッセージを送ることで送信先のリソースをイベント駆動させるといった使い方です。

・個人への通知(A2P)

Amazon SNSから個人の携帯などにSMSメッセージやメールを送ったりする等の使い方があります。以下の通知方法が可能となっております。

  • SMS
  • メール
  • モバイルプッシュ通知

今回は後者の個人への通知(A2P)をメールにて行えるリソースをCDKで定義しデプロイしてみました。

CDKの実装

今回CDKのリソースの定義にはTypeScriptを使用しました。

新しくCDKのプロジェクトを始めるにはまずcdk initコマンドを実行します。

% cdk init --language typescript

npm run watchコマンドを実行すると、TypescriptからJavaScriptへのコンパイルをリアルタイムで行えます。実装中は実行したターミナルを立ち上げたままにしておいてください。

% npm run watch

CDKはリソース毎にライブラリをインストールします。今回は以下をインストールしました。

  • @aws-cdk/aws-sns
  • @aws-cdk/aws-sns-subscriptions
% npm install @aws-cdk/aws-sns
% npm install @aws-cdk/aws-sns-subscriptions

インストールしたライブラリのバージョンはpackage.jsonに以下のように記載されており@aws-cdk/coreの1.132より上のバージョンとなっていました。

"dependencies": {
"@aws-cdk/aws-sns": "^1.134.0",
"@aws-cdk/aws-sns-subscriptions": "^1.134.0",
"@aws-cdk/core": "1.132.0"
}

このような場合に型エラーが発生することが有りましたので、以下のようにバージョン指定をしてインストールする事をおすすめします。

% npm install @aws-cdk/aws-sns@1.132.0 --save-exact
% npm install @aws-cdk/aws-sns-subscriptions@1.132.0 --save-exact

これで以下のようにバージョンが揃いました。

"dependencies": {
"@aws-cdk/aws-sns": "1.132.0",
"@aws-cdk/aws-sns-subscriptions": "1.132.0",
"@aws-cdk/core": "1.132.0"
}

リソースの定義はcdk init実行時に作られたlibディレクトリ内のTypeScriptファイルに対して行います。これがStackと呼ばれる部分になります。

/lib/test.ts

import * as cdk from '@aws-cdk/core';
import * as sns from '@aws-cdk/aws-sns';
import * as subs from '@aws-cdk/aws-sns-subscriptions';

export class TestStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const notificationTopic = new sns.Topic(this, 'notification-topic-by-email', {
      topicName: 'notification-topic-by-email',
    });
    notificationTopic.addSubscription(new subs.EmailSubscription('***********.jp'));
  }
}

リソースが定義できたら次はcdk synthでStackの内容からCloudFormationのテンプレートを生成します。

% cdk synth

以下が生成されたCloudFormationのテンプレートの一部です。Amazon SNS のTopicSubscription のリソースができております。

/cdk.out/TestStack.template.json

  "Resources": {
    "notificationtopicbyemail152F03F8": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": "notification-topic-by-email"
      },
      "Metadata": {
        "aws:cdk:path": "TestStack/notification-topic-by-email/Resource"
      }
    },
    "notificationtopicbyemailabedaisukeclassmethodjp86294EA4": {
      "Type": "AWS::SNS::Subscription",
      "Properties": {
        "Protocol": "email",
        "TopicArn": {
          "Ref": "notificationtopicbyemail152F03F8"
        },
        "Endpoint": "*****************.jp"
      },
      "Metadata": {
        "aws:cdk:path": "TestStack/notification-topic-by-email/*****************.jp/Resource"
      }
    },

最後にcdk deployコマンドでAWSにデプロイします。

% cdk deploy

正常にデプロイできると、サブスクリプションに設定したメールアドレス宛に確認のメールが届きます。 Confirm subscription を押下すると確認が完了し、トピックから発行したメッセージが登録したメールアドレスに届けられるようになります。

AWS上でのリソースの動作確認

cdk deployによりデプロイされたリソースを見てみましょう。 以下のようにAmazon SNSにCDKで定義したトピックとサブスクライリプションが出来上がっています。

トピックから手動でメッセージを発行すると以下のようにメールが届きました!

今回は以上となります!

参考