kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

クロスアカウントなVPCピアリングをTerraformで作る

f:id:kun432:20210228193004p:plain

別のAWSアカウント間でVPCピアリングを、Terraformを使ってやってみました。

目次

構成

こんな感じの構成を作ってみます。

f:id:kun432:20210429200600p:plain

TerraformにおけるVPCピアリング

VPCピアリングでは、

  • リクエスタ(ピアリング接続を依頼する側)
  • アクセプタ(ピアリング接続の依頼を承諾する側)

という形で、ピアリング接続の依頼・承諾というプロセスを踏むことで、接続がアクティブになります。

TerraformでVPCピアリングを行う場合、"aws_vpc_peering_connection" を使います。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_peering_connection

"aws_vpc_peering_connection" には "auto_accept" という、アクセプタ側で自動的に承諾許可を行うオプションがありますが、クロスアカウントの場合は使えないようです。よって、リクエスタ側のTerraformでピアリングを作成し、アクセプタ側はマネジメントコンソール(もしくはaws-cli)で手動で許可してあげることになります。

Terraformは以下のレポジトリに用意しました(そこまで作り込んでないので適宜設定が必要かもです)。

フォルダ構成はこんな感じです。

cross-account-vpc-peering
├── README.md
├── envs/
│   ├── accepter/
│   │   ├── backend.tf
│   │   ├── main.tf
│   │   └── variables.tf
│   └── requester/
│       ├── backend.tf
│       ├── main.tf
│       └── variables.tf
└── modules/
    ├── security-groups/
    │   └── main.tf
    ├── ssm/
    │   └── main.tf
    └── vpc/
        └── main.tf

モジュールを使って、リクエスタ・アクセプタともにVPC周りはほぼ同じものができます。

リクエスタ側にだけ、VPCピアリングの設定が入ってます。

envs/requester/variables.tf で アクセプタ側のアカウントID、VPCのCIDR、VPC IDを指定します。

variable "accepter_account" {
  default = "123456789012"
}

variable "accepter_vpc_id" {
  default = "vpc-12345678901234567"
}

上記を使って、main.tf で VPCピアリングコネクションの作成とルーティングの設定です。サンプルなのでここだけはモジュール使わずベタに書いてます。

resource "aws_vpc_peering_connection" "peer" {
  peer_owner_id = var.accepter_account
  peer_vpc_id   = var.accepter_vpc_id
  vpc_id        = module.vpc.vpc_id

  tags = {
    Name = "vpc-peering-to-accepter"
  }
}

resource "aws_route" "route_vpc_peering" {
  route_table_id            = module.vpc.private_route_table_id
  destination_cidr_block    = var.accepter_vpc_cidr
  vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
  depends_on                = [aws_vpc_peering_connection.peer]
}

aws_vpc_peering_connectionではピアリング先のアカウントIDとVPC ID、自身のVPC IDを設定するだけです。とてもかんたんですね。

では流してみましょう。VPCピアリングの承諾プロセスの関係上、アクセプタ側が先にできている必要があります。

$ cd envs/accepter
$ terraform init
$ terraform plan
$ terraform apply

アクセプタ側のVPC IDを確認します。

f:id:kun432:20210429220712p:plain

リクエスタ側のvariabls.tfのVPC IDを変更しておきます。ではリクエスタもterraform applyしましょう。

$ cd envs/requester
$ terraform init
$ terraform plan
$ terraform apply

ただし、この時点ではVPCピアリングはまだアクティブになっていません。アクセプタ側が承諾をする必要があるためですね。

リクエスタ側のマネジメントコンソールを見てみましょう。VPCの「ピアリング接続」を開きます。

f:id:kun432:20210429221230p:plain

「承諾の保留中」になっています。

では、アクセプタ側で承諾しましょう。同じようにVPCの「ピアリング接続」を開きます。こちらも「承諾の保留中」になっていますので、「アクション」をクリックします。

f:id:kun432:20210429221351p:plain

「リクエストの承諾」をクリックします。

確認画面が出るので「はい、承諾する」をクリックします。

f:id:kun432:20210429221743p:plain

ピアリングができました。では戻りのルーティングを設定しましょう。「ルートテーブルを今すぐ変更」をクリック。

f:id:kun432:20210429221550p:plain

今回の構成では、パブリックサブネットとプライベートサブネット、それぞれにルートテーブルを用意してます。VPCピアリングでつなぐのはプライベートサブネットのみとする想定なので、プライベートサブネットのルートテーブルに、リクエスタVPCのCIDRへはVPCピアリングを使うようにルーティングを設定します。

f:id:kun432:20210429222339p:plain

これでアクセプタ側はOKです。リクエスタ側のマネジメントコンソールに戻って、VPCピアリングの画面を見てみましょう。

f:id:kun432:20210429222545p:plain

こちらもアクティブになっていますね。リクエスタ側ではTerraformでVPCピアリングを使ったルーティングも設定してありますのでこれでOKです。

あとはEC2インスタンスをそれぞれに立ててping疎通などで確認してみてください。

  • accepter/requester-VPCのプライベートサブネットに配置します。
  • セッションマネージャが使えるようにエンドポイントを作成してあります。AmazonSSMRoleForInstancesQuickSetupなどのIAMロールを割り当ててください。
  • セキュリティグループもaccepter/requester-private-sgを用意して、お互いにICMPを通すようにしています。

まとめ

TerraformのVPCピアリングはとても簡単です。同じアカウント内のVPCピアリングなら、アクセプタ側で"aws_vpc_peering_connection_accepter"を使って承諾プロセスの部分もコード化できるので、マネジメントコンソールが不要になります。

ただ、ピアリング先が常に自前だとは限らないですし、Organizationsの場合などアカウントが異なる場合は結局承諾プロセスが必要になるようなので、ベタなマネジメントコンソールでの承諾プロセスを知っておいてもいいのではないかと思います。

日本語に対応したAmazon Lex(V1)を試してみる①

f:id:kun432:20210427220639p:plain

いろいろ忙しくてちょっと久々のエントリ。ついに日本語に対応したAmazon Lexを遅れ馳せながら試してみたいと思います。

目次

Amazon Lexとは?

上記の公式ブログの記載を引用します。

Amazon Lex はチャットボット向けの会話型 AIを提供するサービスで、Alexaと同じテクノロジーを利用した会話インターフェースの構築が可能となります。 音声をテキストに変換するためのディープラーニングを利用した自動音声認識(ASR)と、テキストの意図を認識する自然言語理解(NLU)機能が提供されているため、文字チャットだけではなく、音声入力により、リアルな会話の相互作用を備えたアプリケーションの構築が簡単に行えます。音声には、Amazon Pollyが用いられ、自然な日本語でユーザーに応答し、また発音のカスタマイズ等も可能です。

https://aws.amazon.com/jp/blogs/news/amazon-lex-tokyo/

そして、Lexの画面にある説明を見てみましょう。

f:id:kun432:20210427222318p:plain

Intents/Utterances/Slotsなど、Alexaで見慣れた用語が出て来ていますね。

つまり、Alexaスキル開発を経験したことがあれば、Lexの概要はほとんど理解してるのと同じってことですね。では早速やってみましょう。

余談ですが、"Alexa" から "a"をとると"Lex"になりますね。

はじめる前に

Lexには2つのAPIバージョンがあります。以下の通り、V1とV2ではLambdaのレスポンス形式が異なります。

また、以下のFAQにある通り、V2ではAmazon Connectのコンタクトフローとの統合はできません。

  1. V2 API を使用して作成されたボットを Amazon Connect のコンタクトフローと統合できますか?

いいえ。現在、Amazon Connect のコンタクトフローは既存の V1 API でのみ機能します。V1 コンソールを使用して、ボットを作成し、Amazon Connect と統合することができます。

V2のほうが機能も増えており、将来的にはV2になっていくと思いますが、今回はV1を使ってみたいと思います。

「BookTrip」サンプルを試す

まずは使い方を知るために予め用意されているサンプルの中から「BookTrip」を使ってみたいと思います。

マネジメントコンソールにログインし、Lexの画面を開きます。

f:id:kun432:20210427224000p:plain

初めて使う場合は以下のような画面が表示されるので "Get Started" をクリックします。

f:id:kun432:20210427224108p:plain

ボットの作成画面が表示されます。会話のやり取りが表示されていますね。

f:id:kun432:20210427224320p:plain

デフォルトで"BookTrip"サンプルが選択されていると思うので、ここはそのままで。"TRY A SAMPLE"で"BookTrip"が選択されていること、"Bot Name"に"BookTrip"が指定されているを確認します。

f:id:kun432:20210427224506p:plain

下にスクロールすると、さらに設定があります。まず、言語を「日本語」に変更します。上のやり取りも日本語に変わりますね。

f:id:kun432:20210427225039p:plain

それ以外の項目は以下のとおりとしました。

f:id:kun432:20210427225206p:plain

  • Sentiment analysis
    • Amazaon Comprehendを使って、入力されたテキスト・音声の感情分析の有効・無効を設定します。これはAlexaにはないですね。興味あるので"Yes"にしてみます。
  • COPPA
    • 子供向けサイトの規制に関する法律である「COPPA(Children's Online Privacy Protection Act)」に準拠すべきかどうかを設定します。子供向けのボットを作る場合には有効にする必要があるようで、有効にした場合、制度改善のために入力されたテキストや音声の保存が行われなくなるようです。今回は"No"にしておきましょう。
  • Confidence score threshold
    • インテントの認識に対する信頼度の閾値を設定できるようです。ここは一旦デフォルトのままにしておきます。

IAMロールは自動で作成されるようです。タグも今回は特に指定しません。

設定したら"Create"をクリックします。

ボットが作成されると、以下のような画面が表示されます。

f:id:kun432:20210427230358p:plain

画面の構成を見る前に右上の”Build”がクルクルと回っているのが見えると思います。Alexa開発者コンソールの対話モデルのビルドと同じですね。

f:id:kun432:20210427233546p:plain

ビルドが終わるとメッセージが表示されます。これで対話モデルの構築が完了したということでしょうね。

f:id:kun432:20210427233608p:plain

では画面の構成を見ていきましょう。左のメニューを見てみると、インテントやスロットが並んでるのが見えますね。右に表示されているのは"BookCar_jaJP"インテントのサンプル発話ですね。

f:id:kun432:20210427230716p:plain

もう一つの"BookHotel_jaJP"を見てみると、サンプル発話にスロットが含まれているのがわかりますね。

f:id:kun432:20210427233424p:plain

次にスロットタイプにある"RoomTypeValues_jaJP"を見てみましょう。

f:id:kun432:20210427233931p:plain

スロットの値がいくつか列挙されていますね。つまり、これはAlexaでいう「カスタムスロットタイプ」ということですね。

f:id:kun432:20210427234021p:plain

"Slot Resolution" は "Expand Values" が選択されています。説明を見てみましょう。

f:id:kun432:20210427234225p:plain

「スロット値をトレーニングのデータとして使用し、ユーザからの入力データがスロット値と似ている場合はスロット値として受け取る」とあります。

もう一方の"Restrict to Slot values and Synonyms"の説明も見てみましょう。

f:id:kun432:20210427234507p:plain

こちらは「スロットの値が列挙型として扱われ、ユーザーの値がスロットの値の1つと同じ場合にのみスロットとして受け取る。同義語(シノニム)は、対応するスロット値として解決される。」とありますね。つまり、

  • "Expand Values" の場合は、スロット値と類似した入力データならばスロットに入る。シノニムは使えない。
  • "Restrict to Slot values and Synonyms"の場合は、スロット値は登録されたもののみに限定される。シノニムが使えて、スロット値に変換されてスロットに入る。

ということのようです。このあたり、少しAlexaとは違うようですね。

再度"BookHotel_jaJP"インテントの画面をもう一度見てみましょう。

f:id:kun432:20210427235333p:plain

サンプル発話の下の方に"Slots"というのが見えると思います。

f:id:kun432:20210427235410p:plain

スロットがいくつか並んでいて、スロットタイプにAlexaならおなじみのAMAZON.Cityなどが見えます。これがビルトインスロットタイプなのでしょう。

f:id:kun432:20210427235629p:plain

またこれらのスロットはサンプル発話に含まれていないのですが、"Required"という「必須」を表すチェックボックスと、"Prompt"というそれぞれのスロットを受け取るためのプロンプトが記載されていますね。つまり、これ、ダイアログモデルの設定と同じってことですね。

f:id:kun432:20210427235830p:plain

下に進むと"Confirmation prompt"で確認時の発話とキャンセル時の応答を設定することができます。確認時の発話には受け取ったスロットを含めてありますね。この辺はダイアログモデルとやっていることはほぼ同じですね。

f:id:kun432:20210428000111p:plain

さらに下に進むと"Fulfillment"という項目があり、"Lambda" が選択できることから、ここで受け取ったスロットをバックエンドに渡すのだということがわかります。"Return parameters to client"は多分下にある"Response"のところで固定の応答を返すのではないかなと思いますが、後で見てみましょう。

f:id:kun432:20210428000430p:plain

ボットのテスト

ではテストしてみたいと思います。2つあるインテントのうち、今回は"BookCar_jaJP"のレンタカー予約のほうを使います。右にある"Test Chatbot"をクリックします。

f:id:kun432:20210428000645p:plain

テスト用の画面が開きます。"Chat with your bot"にテキストを入力するか、マイクボタンをクリックして音声入力をすればいいというわけですが、試してみたところマイクでの音声入力がうまくいかないようなので(正しく認識してくれたりしてくれなかったりする)ので、今のところはテキスト入力のほうがベターなようです。

f:id:kun432:20210428000815p:plain

実際にテストしてみた結果はこんな感じです。

f:id:kun432:20210428020137p:plain

最後のところが少しデバッグっぽいですが、ユーザとの対話でスロット値が収集できていることがわかりますね。

また、テストツールの下の方には以下のような状態が表示されます。

  • マッチしたインテント
  • スロット値の収集状況
    • "ElicitSlot" がスロット値の収集途中
    • "ReadyForFullfilment"ですべてのスロット値の収集完了
  • 収集したスロット値

f:id:kun432:20210428023742p:plain

"Detail"をクリックすると、より詳細な情報がJSONで表示され、インテントの信頼度や感情分析の結果なども確認できます。

f:id:kun432:20210428024251p:plain

応答を修正する

応答をLambdaで動的に作ってやりたいところですが、それは次回にして、固定の応答を追加してLex上で完結させるようにしてみます。

"Response" の下にある "Add Message" をクリックします。

f:id:kun432:20210428022738p:plain

応答を設定する入力欄が表示されます。"Message"と"Custom Markup"がありますが、後者はおそらくSSMLで書くのだろうと思います。今回は"Message"で普通に応答内容をテキストで書いてみます。受け取ったスロット値を応答内容に含める場合には {スロット名} みたいに書けばよいです。スロット部分の前後にスペースを入れておいたほうがいいかもですね。こんな感じのテキストを設定してみました。

{PickUpCity} で {CarType} タイプを、{PickUpDate} から {ReturnDate} まで予約しました。ご利用ありがとうございました。

f:id:kun432:20210428022701p:plain

ちなみに、その下にある"Enable response card"はAlexaのカードに似たようなもの、"Wait for user reply" はセッションを終わらせずに次の発話を促すためのプロンプトを設定する箇所のようですが、今回は割愛します。

f:id:kun432:20210428022833p:plain

最後に"Save Intent"をクリックして、インテントを保存します。

f:id:kun432:20210428023324p:plain

そして"Build"をクリックして対話モデルを構築します。

f:id:kun432:20210428023411p:plain

再度テストしてみるとこうなります。

f:id:kun432:20210428024647p:plain

最後の応答が置き換わっているのがわかりますね。かんたんな対話であればLexだけで完結できるということですね。

まとめ

インタフェースもやや異なりますし、多少考え方が違うところもありますが、Alexaスキル開発をやったことがあれば、Lexにはスムーズに入っていけると思います。次回以降でもう少し色々やってみたいと思います。

2021年3月振り返り

f:id:kun432:20210404231011p:plain

2021年3月の振り返りです。1Qも終わっちゃいましたね・・・

今月はあまりアウトプットできなかった・・・

音声関連

  • 自作スキル・アクションの開発に力を入れる
  • Googleアシスタント向けアクションを作って公開する
  • スマホアプリを作って公開する

ここは進捗ゼロ・・・ただ、後述するVoiceflow SDKのデモを作ったので、まあそれを以て良しとしたい・・・

仕事

  • AWSやK8S関連のアウトプットを増やしていく
  • 管理職としてもっとスキルを高めていく

実は色々やってるんだけど、アウトプットできてない。だいぶ知見も貯まってきたのだけどね・・・小さくまとめて出していきたいなぁ。

アウトプット

  • Voiceflowの日本語チュートリアルを充実させる
  • Voiceflowの動画チュートリアルを作る
  • AWSやK8Sのチュートリアルを作る
  • ブログを年間100記事以上書く
  • Advent Calendarに参加する
  • 技術同人誌を出す

ブログはたったの2件。よろしくないな・・・・

VFV2で発表された「Voiceflow SDK」を使ってサンプルを作ってみました。SDKを使うことで、Voiceflowで作った会話フローをいろんな見せ方ができるようになるので、とても柔軟性があがります。ぜひお試ししていただければと。

勉強会やイベントはこのあたりに参加させてもらいました。ありがとうございました。

Voiceflow SDKのウェビナーはざっくり何ができるのか?の雰囲気を掴むのに役に立った。実際に動かしてみて、なるほど中継アプリを作ればいいのか、というところが理解できたら、いろいろ応用できると思う。作ったのは手元でデモ的に動かすためのサンプルなんだけど、LamdbaなりHerokuなりで動かしたり、セッションデータの管理にDynamoDBとか使ったり、すれば商用でも使えるんじゃないかな。githubで公開しているのでぜひお試しください。

今月のAAJUGのAPLハンズオン、今回は裏方でお手伝いをやっていました。個人的にもAPLはあまり積極的になれなかったのだけど、ハンズオンイベントを通して自分的にもいろいろ有益だったし、参加者の皆様の反応もとても良くてよかった。講師の@IgarashisanT さんのおかげですね。資料公開されているので是非試してみてください。DAY2については次月。

JAWS DAYS 2021、今回はEKS周りを中心に聞いてました。EKSのノウハウはあまり多くはないのでとても参考になった。あと、個人的には個人スポンサーでわずかばかりながらも貢献できたかな。

f:id:kun432:20210404225752p:plain

その他

  • ボカロPに俺はなる!
  • 住みやすい・仕事しやすいリモートワーク環境づくりをすすめる
  • 月に1冊本を読む

リモートワーク環境づくりは、あとちょっと。結構いい感じになってきたのでどこかでまとめたい。

相変わらず読書してない。読みたい気持ちが出ない。よくないなぁ。マンガはたくさん読んでるけどw

まとめ

3月はぜんぜんダメだった。一言でいうと忙しすぎる。

忙しいのを言い訳にはしたくないけど、ほぼ毎日残業が続いてる中で、仕事でやらないといけないことを普段もずっと考えてる感じ。なので自分のためのエネルギーがわかないのです。イベントの準備とかはきちんとやってるし、SDKのところも重要なポイントだったのでなんとかかんとか時間と心を作って捻出したけど。。。

当面はこんな感じが続きそうで、どうしたもんかなぁという日々。