御成門プログラマーの技術日記

Microsoft AzureやAngularなどの技術情報を発信します

Global Azure Bootcamp 2019@Tokyo 参加メモ

Global Azure Bootcamp 2019@Tokyoに参加してきました。
備忘録としてメモを公開します。

Azure CosmosDB Deep Dive

  • Cosmos DB

    • データベース、mongodb など様々な形式のDB
    • 全世界であっという間に使える
  • 設計思想

    1. アクセスに対する要求に自由に対応できる
    2. ミッションクリティカルなサービスで使える。遅延が少ない
    3. すぐに使えること
    4. 全世界中にホストする。その場ですぐにレプリケーションできる
    5. 1-4に対してSLAが担保されている
  • どこからのリージョンでも、読み書きもできる。

  • 構成

    • アカウント
      • データベース
        • コンテナ
          • アイテム
  • レプリカ データを実際にもっているもの 複数のレプリカ群からなる
    → データを失われないために複数。
    → リーダーがいて書き込みの指令を受け取り、残りのレプリカに書き込んでいく。
    → 残りのレプリカは読み込み専用。フォワーダーが他のリージョンに情報を送っている。

  • パーティションキー

    • どのレプリカに行くのかが決まる。
    • なんでも構わない。
    • ちょうどいいくらいにばらけているように設定する
    • パーティションは自動的に分散する
  • お金のおはなし(リクエストユニット)

    • 異なるDBタイプをあつかっているので共通した単位が必要
      → RU(リクエストユニット)
    • 1リクエストユニット = 1kbのドキュメントを呼び出す
    • RUをさばくための計算資源を予約され、保証される。
    • RUの割り当てが足りない場合、処理できなくなる。
  • 一貫性モデル

    • 音符マークのやつ
    • 全世界に書き込みを行ったときにレイテンシーが発生するか
    • データベースを書き込んだ時にだれが読めるのか
      • eventual consistency 弱い
      • strong 書き込んだ瞬間に全世界で使える。→トレードオフが存在する。一貫性は最強。レイテンシーがあるかもよ
        • CAP定義 → Consistency、Availability、Patition Toleranceは共存できないという考え方
    • COSMOSDBではこれを5段階で制御できる
    • わかりやすい?
      https://docs.microsoft.com/ja-jp/azure/cosmos-db/consistency-levels#consistency-levels-explained-through-baseball
  • 本日の資料 ここにある内容を話していただけだよ https://github.com/AzureCosmosDB/content/tree/master/decks

Smart Store リファレンスアーキテクチャ Deep Dive!

  • 資料はこちら
    https://speakerdeck.com/miyake/smart-store-deep-dive

  • Smart Store
    https://news.microsoft.com/ja-jp/2019/01/29/blog-smart-store/

  • リファレンスアーキテクチャ

    • 在庫管理や商品管理の共通的な部分はマイクロソフトのソリューションを使う
  • Microsoft Smart Box

    • 小さいAmazon goみたい
    • バックエンドは全部Azure
    • サーバーレスとマイクロサービスの構成になっている
      • サーバーレス
        • できるだけシンプルな基盤にしたい
        • スケーラーびりてぃを柔軟に調整したい
        • リアルタイム性の重視
  • モバイルデバイスへのPush通知

    • プッシュ通知の機能はAppCenterを使用している
    • android firebase cloud messaging
    • App Centerの設定
      • プロジェクト作る
      • ザマリンにコピペ
      • ファイヤベースにプロジェクト作る
      • notification hub はザマリンの場合、ネイティブにがりがりかかないといけない
      • AppCenterならForms側に書けるのでメリットがある。
      • プロジェクトのパッケージ名とfirebaseの設定を合わせないとPush通知が最初だけは来る。

      • http://masatoru.hatenadiary.jp/entry/2018/12/19/235900

  • サーバーレス

    • Azure Functions V2
    • CQRSによるバックエンド
    • Cosmos DB SDKは3.xを使用する
  • リアルタイムWEBによる管理UI

    • SignalIR Serviceによるリアルタイム通知
      • Serverless Mode
        • Hubの実装が不要になる。
      • signalr.jsを使って更新イベントを待ち受ける
        • ほぼコピペで大丈夫
      • Vue.jsでのリアルタイム描画
  • マイクロサービスのデプロイ

    • サーバーレスを一括デプロイする方法
    • ARM Templateを使用する
      • マイクロサービスごとにテンプレートを分割する
      • Linked テンプレート

ARMテンプレートを使い倒せ!ソシャゲを支えるInfra as Codeの極地

  • ARMテンプレートとは

    • 概要
      • 各リソースをJSON形式でテンプレート化
      • ARMテンプレートはあくまでリソースを作るもの。リソースグループより上は作らない
    • 構造

      • parameters
        • デプロイ時にユーザーが入力する値
      • variables
        • テンプレートが持つ値
      • resources
        • デプロイの実行内容
    • 機能

      • アプリケーションの開発と同様に関数やループ処理ができる。
        • 文字列結合 Add
        • 四則演算 Add
        • ループ処理
  • プロジェクトについて

    • インフラ提供とサーバーサイド開発
    • 2社のお客様向けにほぼ同じ設計で提供 →資産と再利用できる
    • 複雑な構成をポータルで作ることができるのか
  • サンプルソース

    • variables
      • PrefixKeyで設定しておく
      • concatを使って接頭辞をセット
      • たくさん作るときに作業ミスせず、命名規則にのっとって作成できる。
    • 発行時に宛先リソースグループをミスることが大きい
    • VMの台数が異なる。初期構成より台数が増える可能性がある。

      • ループ関数を使う
    • 各VMに「連番」で割り当てる必要である。プライベートIPもわける。

    • マニアックな2重ループ
      • linkedテンプレート
  • 利用時の要点

    • 命名規則

      • なるべくシンプルにしたほうがいい
      • 後ろにつけるパターンがいい
    • 依存関係(dependsOn)

    • ファイル分割

    • ドキュメント作成
      • 依存対象のリソースを記述する
      • 中身を理解していない状態で変更しても問題ない部分をしていする。.

サーバーレスは次のステージへ〜 Durable FunctionsによるステートレスなFunctionの実現 〜

  • 今回のセッションの内容
    今回のセッションの内容はここにすべて書いてあるよ
    https://tech-lab.sios.jp/archives/12991

  • Duarable Functions

    • Azure Functionsで実現しようとすると複雑なコードになってしまうものをすごく短いコードで簡単に実現できる。
    • Azure Functions のオーケストレートツール
  • サーバーレスの限界

    • Functionsはロングランニングのバッチ実行などが苦手
  • 構成

    • クライアント関数
      オーケストレーター関数を起動するための関数
    • オーケストレーター関数
      アクティビティ」関数を起動するための関数。
    • アクティビティ関数
      実際の処理を行う関数
  • 例:並列処理

    • DurabuleFunctionsを使わない場合

    • Durable functionsを使った場合

      • たった100行くらい
      • 1/5程度
  • どうやってうごいているのか

    • control Queue
      • クライアント関数を動かす
    • WorkItem Queure
      • オーケストレーター関数を動かす
      • アクティビティ関数を動かす
  • Durable Functions目覚まし

Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~

スマートスピーカスキルは制約が大きい

  • スマートスピーカースキルの概要と得意

    • VUI(Voice User Intesrface)が中心
    • よく使うスキル タイマー 料理のとき、カップ麺のときに超便利
  • ウェイクワード

    • ウェイクワードを変えることで起動するデバイスを分けることができる。
  • クローバーのみバッテリーを内蔵しているので、セッションとかで便利

  • 求められるスキル

    • スマホより便利なとき
      • 運転中、料理中、トレーニング中など手が離せないとき
      • 就寝時にベッドに入ったあと
  • スキルの制約

    • 複雑なパラメーターの入力が必要なものは不向き
    • タイムアウトが非常にシビア
      • 呼びかけたあとにユーザーからの入力がないとすぐにきれてしまう。
    • 返答も音声だけなので理解できる内容には限界がある。
  • スキル開発の流れ

    • バックエンドはHTTPのJSONでやり取り
    • Azureでバックアップを実装する
      • FunctionsとLogic Appsがよく出てくる
  • Logic Appsを使って完全ノーコーディング
    詳細はこの記事
    https://qiita.com/himarin269/items/f5d00e649899288e8596

    • クロスプラットフォーム対策 = ロジックの共通化をする
    • Logic Apps
      • HTTPをトリガーとするフローを作ることができる
      • ロジックアップ同士やAzure内外のサービスと連携しやすい
      • JSONの扱いが簡単
        「サンプルのペイロードを使用してスキーマを生成する」サンプルJSONからJSONの解析を行ってくれる。
      • Dialogflowと連携時、URLを一部変える必要がある
  • AzureFunctionsでのスキル開発

  • コードを書きたいなら、Azureの場合ならFunctionsが圧倒的におすすめ
  • コールドスタートの遅さがVUIの大敵
    • 動くまで20分くらいかかることもある
    • 特にVUIは応答に長いと不安にアンる
    • タイムアウトすることもある
  • コールスタート対策

    • App Serviceプランを使う
      • 安いというメリットが失われる
      • 最低でもS1プランが必要になる
    • 定型文を返しているすきにFunctionsAppを起動する
      • LogicAppで受けて、定形レスポンスを返すタイミングでFunction Appを空のリクエストして起こしておく。
  • Durable Functionsを使ってスキルの常識を覆す

    • ラインに投降した内容をスピーカーに話させる。
    • Lineとクローバーをつなげているのは「Durable Functions」のみ
    • ContinueAsNewで状態の保持

セミナー参加メモ「目指そう!クラウドネイティブ ~ その全体像と技術事例」

マイクロソフトの開催する「目指そう!クラウドネイティブ ~ その全体像と技術事例」セミナーに参加してきました。

microsoft-events.connpass.com

参加時にメモった内容を共有します。

「本格化するクラウド ネイティブ時代に向けて 押さえておきたい技術要素とアーキテクチャの変化

  • Cloud NativeとはCNCFが定義している

  • サーバーレス・・・PaaSと比べ、スケーリングも気にする必要がない。
    AppService、Functions、Logic App、Azure Kuberetes Service(AKS)、ServiceFabric

  • Docker Container

    • コンテナーのデファクトスタンダード
    • コンテナー型仮想化技術→よりスケーラビリティを持つ。
  • コンテナーのメリット

    • 一度イメージを作ると、コンテナーが動く環境ならどこでも動作すること
    • 例:開発が作ったコンテナーのイメージが他の人の環境になったら動かないという現象が発生しない。
    • Dockerコンテナーは他者のコンテナー環境でも動くマルチテナントである。
  • Azure Dev Ops(旧vsts)

    • コンテナのCI/CD
    • WorkItemの管理
    • DevOpsの要 PipeLine
    • TestPlans 自動テストを行う
  • クラウドネイティブを目指す

    • 既存アプリからIaaSへの移行は簡単(Rehost)
    • 本格的にクラウドに持っていき、クラウドメリットを享受する(モダナイズ)
      • コンテナ、PaaS、CI/CDを取り入れることが最初のステップ
      • 最終的にはアーキテクチャの見直しも必要 → マイクロサービス、サーバーレス
  • マイクロサービス

    • 小さいサービス単位(コンテナもその1つ)
    • では粒度をどうすればいいか
    • 最初は少しずつサービスを小さくしていこう
    • マイクロサービスによって個々のコンテナが小さくなり、量が増える
      • オーケストレーターが必要になってくる。→「Azure Kubernetes Service(AKS)」
  • azure Dev Spaces(プレビュー)

    • AKS上でコンテナ実行とデバッグ実行が可能
    • チーム開発をやりやすくする
    • 複数人でのコンテナ開発で自分だけの変更コンテナを確認できる
    • 他の人が作っている変更に影響を与えない
    • 自分の環境だけ変更する。
  • Blue/Greenデプロイメント

    • Immutableインフラストラクチャ
  • カナリアリリース

    • トラフィックを少しずつ新しい環境に移す。何かあればトラフィックを戻す。
    • AppServiceのデプロイメントスロット→トラフィック率の指定もできる
  • Cloud Native Database周りはどうするべきか

    • サービス単位でデータベースを切り分ける
    • できればマネージドサービス
    • SQL Database、CosmosDB(高速レプリケーション)
  • PaaSとFaaS

    • FaaSはスケーリングを含めて考えてくれる
    • Azure Functions
      • トリガー、DBの変更キャッチ
      • 使ったときだけ課金
      • 自動スケーリング
      • シナリオ
        • タイマー駆動 バッチ
        • IOTなどデータ更新時にトリガー
        • アプリのバックエンド
        • Botのバックエンド←最近多い
  • Azureアーキテクチャリファレンス
    Azureアーキテクチャセンター
    docs.microsoft.com

「オイシックス・ラ・大地におけるマイクロサービス高速開発に向けた取り組み」

  • 資料
    speakerdeck.com

  • ECサイトのお話 

    • 19万人を超える会員
    • 「おいしっくすくらぶ」 サブスクリプションモデル
  • ECサイトのマイクロサービス化の背景

    • 2000年に作りJavaでできている。
    • オンプレのOracle(編集しづらいという意味で"神オラクル"というあだ名)に対してモノリシックな構成だった。
  • アプローチ「ストラングラーパターン」

    • 既存の機能を徐々に変えていく。
  • マイクロサービスの開発プロセス

    1. チェックアウト
    2. インターフェースデザイン
    3. テストコード
    4. コンテナー化
    5. デプロイ
    6. パブリック
  • インターフェースデザインSwaggerを使用

「[導入事例] 小さく始めるクラウドネイティブ」

  • 資料
    speakerdeck.com

  • GlowLio

    • マルチテナントな広告プラットフォーム
  • スクラム一週間スプリント

    • CIはしているが、CDはしていない。
    • リリースは手作業
    • Azureだけでなく、GCP BigQueryやAWSのメディアコンバートなども使用している
  • クラウドを使わない手はない

    • 小さい会社の小さいチームの新規事業でインフラを用意する暇はない。
  • マネージドサービスやSaaSに頼る

    • AKSDatadog
  • 広告配信

    • Docker On Azure VM
    • 少しでも落ちるとそれが自社どころか、お客さんの売り上げに関わるから落とすことができない
  • 管理画面

  • すべてのアプリをDockerizeする

    • ポータビリティの向上
    • インフラの仕事からアプリ開発の仕事をメインにする
  • 「自前運用」 or 「マネージドサービス」

    • 自前でやるより確実に安定
    • 自前でもマネージドでも死ぬときは死ぬ
  • 「Docker On VM」 or 「K8S」

    • 求める要件による(SLO/SLA)
    • 「落ちたら困る」or「落ちてもすぐ復旧すれば許される」
    • 使ってもいいところにはチャレンジ
      • 一切のダウンタイムが許されない広告配信は「Docker On Azure VM」
      • 管理画面は多少のダウンタイムが発生しても大丈夫なので「K8S」
  • チャレンジすることを見極める
  • 自分に頼らずクラウドに頼る
  • 適材適所でクラウドを利用する

  • K8Sを使ってよかった点

    • Dockerコンテナをオーケストレートできる
    • 考えることは少ない
    • バージョンアップは設定ファイルを変えるだけで簡単に行える
  • K8Sを使って悪かった点

    • 難しい
    • 何か問題が起こったとき、理由がすぐわからずつらかった
    • 遅い
    • 学習コストが高い

Azure Functionsのタイマートリガーをデバッグ実行する方法

Azure Functionsのタイマートリガーをデバッグ実行したい

Azure Functionsのタイマートリガーを使用するとスケジュールした時間に関数を起動できるようになりますが、開発中はいちいちスケジュールしたタイミングまで待ちたくないですよね。

docs.microsoft.com

デバッグ実行時に関数が実行されるようにする

変更する箇所は一か所です。
スケジュールを設定しているTimerTriggerAttributeにプロパティを追加するだけです。

  • 変更前
    TimerTrigger("0 0 * * * *")

  • 変更後
    TimerTrigger("0 0 * * * *",RunOnStartup =true)

これでデバッグ実行開始時に関数が実行されるようになります。
ちなみに意図しないタイミングで関数が実行される可能性があるため、Azure上に発行する際にはプロパティは外したほうがいいらしいです。

参考ページ

docs.microsoft.com

Azure SQL DatabaseでAzureActiveDirectory認証を設定する

AzureのSQL DatabaseをAzureActiveDirectory(以下、AAD)のユーザーで認証する方法を紹介します。

Azure SQL Databaseとは

Azure SQL DatabaseはMicrosoft Azureの提供するPaaSのサービスです。
SQL Serverと名前が似ているので、勘違いされますが別のサービスですのでご注意ください。
azure.microsoft.com

今回の例はSQL Database エラスティックプールを使用しています。
そのため、画面の表示がシングルデータベースの場合と差異がある場合がございますが、 ご了承ください。

SQL Database側の設定(Azure ポータル)

Azureポータルで"Active Directory 管理者"を設定する

SQL DatabaseでAADに所属しているユーザーを認証できるようにするには、 Azureポータルで"Active Directory 管理者"を設定する必要があります。 「Azureポータル」→「作成したSqlServer」→「Active Directory 管理者」→「管理者の設定」
f:id:tt-suzukiit:20190125180212p:plain

管理者にするユーザーを検索し、追加します。
f:id:tt-suzukiit:20190125181127p:plain

「保存」ボタンをクリックします。 これでAD管理者の設定は終了です。

クライアント端末からアクセスできるようファイアウォール設定を行います。

SQLDatabaseにアクセスできるクライアント端末のIPアドレスの許可設定を行います。
「Azureポータル」→「作成したSqlServer」→「ファイアウォールと仮想ネットワーク」→「クライアントIPの追加」
f:id:tt-suzukiit:20190125184502p:plain
「保存」ボタンをクリックします。
Azureポータル側での設定は以上です。

接続方法

SQLServer Management Studio(以下、SSMS)を使用して接続を行います。

SSMSのインストールはこちらから
接続情報を入力します。 f:id:tt-suzukiit:20190125181509p:plain

項目 設定値
サーバーの種類 データベースエンジン
サーバー名 各自認証サーバーの名称を入力
認証※ Active Directory - MFAサーバーで汎用
ユーザー名 登録したAD管理者のアドレスを入力

私のAADアカウントは多要素認証が設定されているため、
認証で「Active Directory - MFAサーバーで汎用」を選択しております。
多要素認証を設定していない場合、「Active Directory - パスワード」を選択してください。

接続を選択すると、マイクロソフトアカウントの認証画面が表示されますので、
指示に従い、認証情報を入力すると接続できることが確認できます。 f:id:tt-suzukiit:20190125182735p:plain

ただこの段階だとAD管理者で設定したユーザー以外はログインできないため、
ユーザー追加の設定を行う必要があります。

ADユーザーをSQLDatabaseで認証できるように追加する

ユーザーを追加しましょう。
これでADユーザーを追加することができます。

--ユーザー(×××@△△.com)追加
CREATE USER [×××@△△.com] FROM EXTERNAL PROVIDER;

--ユーザー(×××@△△.com)にdb_owner権限を付与する
ALTER ROLE db_owner ADD MEMBER [×××@△△.com];

最後に

共有のユーザーID、パスワードを使わないようにするために、
AD認証を使用する方法は有効な手段だと思います。
大事なデータベースを守るためにもAD認証を取り入れましょう。

参考ページ

Azure Active Directory 認証を構成する - SQL | Microsoft Docs

SQL Server Management Studio (SSMS) のダウンロード - SQL Server | Microsoft Docs

AzureWebAppsとAzureActiveDirectoryに独自ドメインを追加する

WebAppsやAzureActiveDirectoryのURLは初期状態下記のドメインで固定です。

  • 〇〇.onmicrosoft.com
  • https://△△.azurewebsites.net/

ただ、自分で独自のドメインを使用したいときもありますよね。
そういうときはドメイン名の設定を行いましょう。

今回行うこと

  • ドメインを購入する
  • AzureActiveDirectoryにカスタムドメインを追加する
  • WebAppsのURLにドメイン名を追加する

ドメインを購入する

まずドメインを購入する必要があったのですが、
Azure経由で購入すればAzureの請求にドメインの代金も含まれるので管理しやすいと思い、
Azureポータル上にあるWebAppsのドメイン購入を使用してドメインを購入しました。

「App Service」→「カスタムドメイン」→「App Service ドメイン」→「ドメインの購入」 f:id:tt-suzukiit:20190109182030p:plain

ドメインの購入画面は下記のような画面が表示されますので画面の指示に従って入力してください。
既定のホスト名の割り当てはどちらもチェックを入れます。 f:id:tt-suzukiit:20190110185153p:plain

OKを入力するとドメインの購入処理が始まります。
ドメインの購入が完了したら、リソースに「App Service ドメイン」と「DNSゾーン」が作成されていると思います。

AzureActiveDirectoryにカスタムドメインを追加する

次にAzureActiveDirectoryにカスタムドメインを追加していきましょう
基本的には下記ページを参照に進めていけると思います。
ドキュメントと違う部分のみ記述していきます。 docs.microsoft.com

「ドメイン レジストラーに DNS 情報を追加する」の部分はAzure DNSを使用する。

今回ドメインはAzureから購入したため、ドメイン レジストラーではなく、Azure DNSを使って情報を追加していきます
docs.microsoft.com さきほどドメイン購入完了時に作成された「DNSゾーン」のリソースを選択します。
「+レコードセット」のボタンをクリックしてDNSレコードを追加しましょう。 f:id:tt-suzukiit:20190109184851p:plain
追加するレコードの値は下記の通り設定します。

項目
名前 @
種類 TXT
TTL 60
TTLの単位
設定する値の取得先はドキュメントの「ドメイン レジストラーに DNS 情報を追加する」の部分参照

以上でDNSレコード設定の追加は完了です。
Azureで扱っているDNSレコードについて詳しく知りたいかたは下記ページをご参照ください。

onarimonstudio.hatenablog.com

また、「カスタム ドメイン名を検証する」の部分は検証する前から利用可能になっていたので飛ばしました。

AzureActiveDirectoryのドメイン追加が完了

これにて設定完了です。
AzureActiveDirectoryのカスタムドメインプレートで今回追加したドメインをプライマリに設定しておきましょう。
AADのトップ画面などにドメイン名が反映されるのは少し時間がかかるかもしれません。

確認のため、ユーザー追加で今回のドメイン名を使ったユーザーを追加できるようになったことを確認しておきましょ。

WebAppsに独自ドメインを設定する

ホスト名を追加する

Webapp→カスタムドメイン→ホスト名の追加を選択します。
f:id:tt-suzukiit:20190110185113j:plain ホスト名に追加するルートドメイン名を入力します。
そうすると、下記の画面のようにドメインの所有権の部分でエラーが出ると思います。
f:id:tt-suzukiit:20190110180734p:plain
エラー画面の指示通りにDNSレコードを追加しましょう。

DNSレコードを追加する

Azure DNSでDNSレコードを追加します。
先ほども使用したDNSゾーンを選択します。

Aレコードを追加します。「+レコードセット」を選択

項目
名前 @
種類 A
TTL 60
TTLの単位
ドメインの所有権の部分で発生したエラーで指示された値

TXTレコードも追加しますが、TXTレコードは先ほど同じ種類のレコードを作成済みですので
既存の名前@、種類がTXTの既存のレコードを選択しましょう。

項目
名前 @
種類 TXT
TTL 60
TTLの単位
ドメインの所有権の部分で発生したエラーで指示された値

ホスト名を追加画面に戻りホスト名を追加する

先ほど下記のようにエラーが出ていたと思いますが、
DNSレコードを追加したことでエラーがなくなり、
「ホスト名の追加」ボタンを選択できるようになっているので選択します。 f:id:tt-suzukiit:20190110180734p:plain

選択すると、下記の画像のようにドメインが追加されます。
画像は違いますが「SSLバインディング」の部分はまだ未接続の状態になっていると思います。
f:id:tt-suzukiit:20190110183028p:plain

これでWebAppsのアプリに対して独自のドメインでアクセスできるようになります。

【WebAppsの認証を入れている人のみ】応答URLに今回追加したドメインのURLを追加します

WebAppsにAD認証を入れている人は応答URLに今回追加したドメインのURLを追加しないとエラーになります
下記2点のURLを追加しましょう。

  • https://<追加したドメイン名>
  • https://<追加したドメイン名>/.auth/login/aad/callback

API Apps を使用している人はCORSの設定も追加するのを忘れないようにしましょう。

完成!! ブラウザで表示できるか試してみよう

ブラウザのURLバーに追加したドメインを入力してみましょう。
WebAppsのアプリにアクセスできたら成功です。
現段階ではSSL証明書の設定を行っていないため、ブラウザで警告が表示されると思います。

WebAppsで独自ドメインを使用する場合、SSL証明書の設定を自分で行う必要がある

WebAppsにSSL証明書をバインドする方法については別記事で紹介しようと思います。

参照ページ

docs.microsoft.com

docs.microsoft.com

docs.microsoft.com

Azure DNSがサポートするDNSレコードについてまとめました【MCP 70-533試験対策】

2018年12月31日に終了する「MCP 70-533試験」に駆け込み合格を狙っているため、
猛勉強を勉強を行っています。

MCP 70-533試験終了についての情報はこちらの記事でまとめております。
onarimonstudio.hatenablog.com

その中でもDNSの分野がとても苦手だったのでDNSレコードについての基礎知識をまとめます。

DNSレコードとは

DNSレコードについては一度こちらのページを見ていただくと、
わかりやすいと思います。

https://wa3.i-3-i.info/word12284.html

僕の解釈ではレコードによって入るデータが違うってこと。
これを覚える必要があると思います。

AzureDNSでサポートしているDNSレコードの種類

一般的な DNS レコードの種類である下記のDNSレコードをサポートしている。

  • Aレコード
  • AAAAレコード
  • CAAレコード
  • CNAMEレコード
  • MXレコード
  • NSレコード
  • PTRレコード
  • SOAレコード
  • SRVレコード
  • TXT レコード

各DNSレコードについてのまとめ

Aレコード

題名 設定
正式名称 Address Record
日本語 IPアドレスレコード
設定例 onarimonstudio.hatenablog.com IN A 13.115.18.61
説明 IPアドレス(IPv4)を設定する

AAAAレコード

題名 設定
正式名称 Address Record
日本語 IPアドレスレコード
設定例 onarimonstudio.hatenablog.com IN A 13.115.18.61
説明 IPアドレス(IPv6)を設定する

MXレコード

題名 設定
正式名称 Mail eXchanger Record
日本語 メール交換手レコード
設定例 onarimonstudio.hatenablog.com IN MX 10 mail.onarimonstudio.hatenablog.com
説明 そのドメイン名で利用するメールサーバーの情報を記述したものです。数字は優先順位です。数字が低い方の値が優先されます。

PTRレコード

題名 設定
正式名称 PoinTeR Record
日本語 ドメイン名を指し示すレコード
設定例 13.115.18.61 10 IN PTR onarimonstudio.hatenablog.com
説明 IPアドレスに対するドメイン名が書かれた行です(つまりAレコードの逆)

Time-To-Live

Time-to-Live (TTL) は、各レコードが再度クエリが実行されるまでクライアントによってキャッシュされる期間を指定します

ワイルドカード レコード

作成中

CAA レコード

題名 設定
正式名称 Certification Authority Authorization Record
日本語 証明機関を示すレコード
設定例 onarimonstudio.hatenablog.com 10 IN CAA 0 issue ca.onarimonstudio.hatenablog.net
説明 メインの証明書を発行する権限のある証明機関 (CA) を指定

上記の設定例の場合、
ドメイン名 'ca.onarimonstudio.hatenablog.net'の所有者またはその代理人以外は、
onarimonstudio.hatenablog.com の証明書を発行できないことを設定しています。

CNAME レコード

題名 設定
正式名称 Canonical NAME Record
日本語 別名正規名
設定例 sub.hatenablog.com IN CNAME onarimonstudio.hatenablog.com
説明 別名の正規名(あだ名って意味らしい)

この設定を行うことで「onarimonstudio.hatenablog.com」も「sub.hatenablog.com」も
同じIPアドレスとして扱われる。

CNAMEレコードとはなんですか?すいません、DNSなどの勉強をしているのですが、C... - Yahoo!知恵袋

あるwwwサーバのホスト名は実際には eva.abc.com だったとします。
しかし、公には www.abc.com としたい。
そんなときにでてくるのがCNAMEですね。

NSレコード

題名 設定
正式名称 Name Server Record
日本語 ドメイン名サーバー指定レコード
設定例 onarimonstudio.hatenablog.com IN NS dns.onarimonstudio.hatenablog.com
説明 Nameという名のとおり、ドメイン名を問い合わせるDNSサーバーの名前が書かれている。

SOA レコード

題名 設定
正式名称 Start Of Authority Record
日本語 認証開始レコード
設定例 作成中
説明 権威を持つゾーンの開始を示す

このページの説明がわかりやすかったです。
https://faq.bit-drive.ne.jp/bit-drive/web/knowledge/faq1253.html

SPF レコード

題名 設定
正式名称 Sender Policy Framework Record
日本語 送信規則レコード
設定例 作成中
説明 ドメイン名を使って電子メールを送信することができる電子メール サーバーを指定するために使用されます

SPF レコードは Azure DNS でもサポートされていますが、TXT レコード タイプを使用して作成する必要があります。
送信した電子メールが受信者に迷惑メールとして分類されないようにするには、SPF レコードを正しく構成することが重要です。

SRV レコード

題名 設定
正式名称 SeRVice recordレコード
日本語 サービスレコード
設定例 作成中
説明 ドメインで提供されているサービスの詳細な情報を記述する

TXT レコード

題名 設定
正式名称 TextRecord
日本語 テキストレコード
設定例 onarimonstudio.hatenablog.com IN TXT "ここは自由に記述できる"
説明 ドメイン名を任意のテキスト文字列にマップするために使用されます。

Azureポータルを使ったDNSレコードの作り方の例

docs.microsoft.com

参考ページ

docs.microsoft.com

rms-digicert.ne.jp

https://wa3.i-3-i.info/word12284.html

https://wa3.i-3-i.info/word12290.html

https://wa3.i-3-i.info/word12285.html

Azure Functionsの拡張機能「Durable Functions」で複数関数の並列実行を行う(ファンアウト/ファンイン)

前回記事で紹介した通り、
「Durable Functions」にはいくつか機能がありましたが、
今回は、複数関数の並列実行を行う方法(ファンアウト/ファンイン)を試してみます。

前回記事

今回の記事はDurable Functionsの基礎的な作り方の部分は省きます。
基礎的な作り方に関しては下記ページで紹介してますのでご参照ください。 onarimonstudio.hatenablog.com

どういう機能を実装するのか

今回はメッセージを出力する関数を並列で実行します(ファンアウト/ファンイン)。
図にするとこんな感じです。
f:id:tt-suzukiit:20181212201503p:plain

ファンアウト/ファンインは、複数の関数を並列に実行してすべてが完了するまで待機するパターンです。 複数の関数から返された結果に基づいて集計作業が行われる場合があります。

Durable Functions のファンアウト/ファンイン シナリオ - Azure | Microsoft Docs

実際に作ってみる

まずは準備

前回記事で作ったところまで用意します。 「FunctionParallel.cs」という名前でAzure関数を追加しています。 onarimonstudio.hatenablog.com
正直、並列処理の例としてはわかりづらいです。すみません。

並列処理を記述する

「FunctionParallel.cs」をまるっと書き換えます。 今回コードの中で並列処理の1つ目の関数のみ5秒のスリープの関数を仕込んでます。

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace DurableFuncAppFanoutFanin
{
    public static class FunctionParallel
    {
        [FunctionName("FunctionParallel_HttpStart")]
        public static async Task<HttpResponseMessage> HttpStart(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
    [OrchestrationClient]DurableOrchestrationClient starter,
    ILogger log)
        {
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync("FunctionParallel", null);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }

        [FunctionName("FunctionParallel")]
        public static async Task<List<string>> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var outputs = new List<string>();
            outputs.Add(await context.CallActivityAsync<string>("FunctionParallel_Hello", "FunctionStart"));

            var tasks = new Task<string>[4];
            tasks[0] = context.CallActivityAsync<string>("FunctionParallel_Hello", "onarimon");
            tasks[1] = context.CallActivityAsync<string>("FunctionParallel_Hello", "programmer");
            tasks[2] = context.CallActivityAsync<string>("FunctionParallel_Hello", "Hello");
            tasks[3] = context.CallActivityAsync<string>("FunctionParallel_Hello", "World!!");

            await Task.WhenAll(tasks);
            foreach (Task<string> task in tasks)
            {
                outputs.Add(task.Result);
            }
            outputs.Add(await context.CallActivityAsync<string>("FunctionParallel_Hello", "FunctionFinish"));


            return outputs;
        }

        [FunctionName("FunctionParallel_Hello")]
        public static string SayHello([ActivityTrigger] string name, ILogger log)
        {
            if (name == "onarimon") {
                System.Threading.Thread.Sleep(5000);
            }

            log.LogInformation($"{name}.");
            return $"{name}";
        }
    }
}

デバッグ実行してみる

デバッグ実行すると、前回同様statusQueryGetUriが出力されるのでコピーして実行

出力結果のoutputの部分のみ抽出するとしっかりメッセージが出てることを確認できました。
output":["FunctionStart","onarimon","programmer","Hello","World!!","FunctionFinish"]

並列処理の関数を1つだけ遅延させたけど結局await Task.WhenAll(tasks);の部分で並列処理の関数が全部終わるの待ってから結果出力してるから、 出てくる順番はコード通りなってますね。

まとめ

Durable Functionsで並列処理ができるようになると下記のようなメリットがあります。
今度はもっとまともな例で作れるように頑張ります。

通常の関数では、関数が複数のメッセージを 1 つのキューに送信することでファンアウトが行われます。 しかし、ファンインして戻すことはこれよりずっと難しくなります。 キューによってトリガーされる関数が終了し、関数の出力が格納される時間を追跡するように、コードを記述する必要があります。 Durable Functions 拡張機能は、比較的単純なコードでこのパターンを処理します。

参考ページ

docs.microsoft.com qiita.com qiita.com

Azure Functionsの拡張機能「Durable Functions」の基礎を知るためにとりあえずデプロイしてみた

最近「Azure Functions」がらみでよく話に出る「Durable Function」のクイックスタートをやってみました。
備忘録的に作った際のメモを残そうと思います。

Durable Functions の概要

概要については公式ページ参照 docs.microsoft.com

Durable Functions の主な用途は、サーバーレス アプリケーションにおける複雑でステートフルな調整の問題をシンプルにすることです。 次のセクションでは、Durable Functions を使用することでメリットがある、いくつかの典型的なアプリケーションのパターンを示します。
パターン #1: 関数チェーン
パターン #2: ファンアウト/ファンイン
パターン #3: 非同期 HTTP API
パターン #4: 監視
パターン #5: 人による操作

Azure Functionsを連続、並列で実行したりする機能なのかなぁってイメージです。
機能、事例とかを知るためにTechSummit2018でMicrosoftの牛尾さんがDurable Functionsのセッションやってたから見てみようかなと思っています。

さらっと作ってみた

Azure Functionsのプロジェクトを作る

Visual Studioから作ります。
新しいプロジェクトで「Visual C#」→「Cloud」→「Azure Functions」 f:id:tt-suzukiit:20181210184506p:plain

バージョンを「Azure Functions v2(.NET Core)」
テンプレートは「なし」
ストレージアカウントは「ストレージエミュレーターf:id:tt-suzukiit:20181210184522p:plain

プロジェクトに新しい関数を追加する

「プロジェクトを右クリック」→「追加」→「新しいAzure関数...」
f:id:tt-suzukiit:20181210184906p:plain

「Azure関数」を選択し、名前を付けて追加をクリック
f:id:tt-suzukiit:20181210184959p:plain

「Durable Functions Orchestration」を選択してOKを選択する f:id:tt-suzukiit:20181210185056p:plain

下記のようなDurable Functionsのコードが自動生成される。

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace DurableFuncApp
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<List<string>> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var outputs = new List<string>();

            // Replace "hello" with the name of your Durable Activity Function.
            outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "Tokyo"));
            outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "Seattle"));
            outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "London"));

            // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
            return outputs;
        }

        [FunctionName("Function1_Hello")]
        public static string SayHello([ActivityTrigger] string name, ILogger log)
        {
            log.LogInformation($"Saying hello to {name}.");
            return $"Hello {name}!";
        }

        [FunctionName("Function1_HttpStart")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
            [OrchestrationClient]DurableOrchestrationClient starter,
            ILogger log)
        {
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync("Function1", null);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

HttpStartで関数を起動し、RunOrchestrator(名前はFunction1)で
「Function1_Hello」関数を3回連続で実行するコードみたいですね。

デバッグ実行で試す

デバッグ実行に成功すると、ローカルホストのURLが出力されるので、
このURLをブラウザ上で実行する。 f:id:tt-suzukiit:20181210190509p:plain

ブラウザ上でURLをたたくと下記のような文字列が出力される。 f:id:tt-suzukiit:20181210190647p:plain

{"id":"4fbb74e39ae04151a6fce230198617f4","statusQueryGetUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4?taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","sendEventPostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","terminatePostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","rewindPostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w=="}

上記文字列の中から「statusQueryGetUri」をコピーし、ブラウザ上で実行すると実行結果が表示されました。

出力結果

"Hello Tokyo!","Hello Seattle!","Hello London!"が出力されており、
「Function1_Hello」関数が3連続で呼ばれていることがわかりました。

{"instanceId":"4fbb74e39ae04151a6fce230198617f4","runtimeStatus":"Completed","input":null,"customStatus":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2018-12-10T08:58:29Z","lastUpdatedTime":"2018-12-10T08:58:37Z"}

Azureに発行する

発行する方法はいつもと変わらないので省略します。
動作は、デバッグ実行時と変わりません。

参考ページ

docs.microsoft.com

【Azure Functions 2.0】NUnitを使用して、自動テストを行う

今回はAzure Functionsの関数に対してNUnitを使って、自動テストを行います。

前準備

前回の記事でVisualStudioから作ったソースコードをそのまま使用します。
ソースコードの元の内容については下記を参照。 onarimonstudio.hatenablog.com

テストプロジェクトを作成します

テスト用のプロジェクトを新規で追加します。

NUnitを使用するためにパッケージをインストールします。
「プロジェクト」→「Nugetパッケージの管理」
下記5点のパッケージをインストールします。
NUnit
NUnit3TestAdapter
Microsoft.NET.Test.Sdk
Moq
Microsoft.AspNetCore.App

テストコードを記述します

追加したテストプロジェクトにクラスを追加し、
テストコードを記述します。

using Microsoft.AspNetCore.Http;
using Moq;
using NUnit.Framework;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;

namespace Tests
{
    public class Tests
    {
        [Test]
        public async Task 出力結果が正しいかのテスト()
        {
            var httpRequestMoq = new Mock<HttpRequest>();
            httpRequestMoq.Setup(x => x.Query["name"]).Returns("onarimonprogram");
            httpRequestMoq.Setup(x => x.Body).Returns(new MemoryStream());
            var response = await HelloFunctionsAppHttpTrigger.Function1.Run(httpRequestMoq.Object, new Mock<ILogger>().Object);

            //関数の実行が成功しているかをテスト
            Assert.True(response is OkObjectResult);

            var responseOkResult = (OkObjectResult)response;
            //出力値が正しく出力されているかをテスト
            Assert.AreEqual("Hello, onarimonprogram", responseOkResult.Value);
        }
    }
}

テストを実行してみる

「テスト」→「ウィンドウ」→「テスト エクスプローラー」
全てを実行を押すと、テストが実行され、結果が出力されました。 f:id:tt-suzukiit:20181206204816p:plain
これで自動テストができるようになりました。

最後に

自動テストができるようになったので、
今度、FunctionsのCI/CDを紹介できたらと思います。

参考ページ

blog.okazuki.jp

【Azure Functions 2.0】Visual Studioを使って関数を作成し、デバッグ実行後、Azure上へ発行する

今回は以前AzurePortalから作成したAzure FunctionsのHelloWorld関数をVisual Studioから ローカル実行を行い、その後、Azure上に発行する方法を紹介します。

Azureポータルから作成する方法

onarimonstudio.hatenablog.com

VisualStudioからプロジェクトを作成する

VisualStudioの新規プロジェクト作成画面を開き、
「Visual C#」 → 「Cloud」 と選択すると、「Azure Functions」があるのでこちらを選択して作成します。 f:id:tt-suzukiit:20181205202530p:plain

Functionsの設定画面が開くので下記の通り設定します。
今回はアクセス権の設定は行いません。

f:id:tt-suzukiit:20181205202750p:plain

項目 設定値
バージョン Azure Functions v2(.NET Core)
テンプレート Http trigger
ストレージアカウント ストレージエミュレーター
Access right Anonymous

設定後、OKを押すと、自動的にHTTPトリガーのテンプレートが展開されます。

自動作成されたコード

Function1.cs

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace HelloFunctionsAppHttpTrigger
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}

デバッグ実行してみたら、エラーが発生

とりあえずこの時点でデバッグ実行できるはずなので、F5を押して実行してみたらエラーになった。 f:id:tt-suzukiit:20181205203950p:plain

致命的なエラーが発生し、デバッグを終了する必要があります。詳細については、MicrosoftヘルプとサポートWebサイトを参照してください。HRESULT=0x8000ffff。エラーコード=0x0。

Visual Studioのアップデートを最近していないことが原因だった

なんかアップデート周り怪しいなと思い、「ヘルプ」→「更新プログラムの確認」
思った通り、Visual Studioのアップデートを最近してなかったので、更新したら解決した。

いざ再デバッグ実行

デバッグ実行が成功するとこんなコンソールが出てくる。 f:id:tt-suzukiit:20181205211209p:plain コンソールのURLをコピーしてブラウザ上で実行してみる。

http://localhost:7071/api/function1?name=onariomonprogram

「ハロー御成門プログラマー」ということでデバッグ実行は通った。
f:id:tt-suzukiit:20181205204816p:plain

Azure上に発行する

「ソリューションエクスプローラー」→「ソリューションを選択して右クリック」→発行
このままプロファイルの作成をクリック f:id:tt-suzukiit:20181205205139p:plain

Azure上のアプリ名とかサブスクリプション名を聞かれるので適当に設定して作成をクリック。
下の画面が出たら「発行」を押す。
Azureの関数のバージョンを更新するか聞かれたら「はい」を選択。 f:id:tt-suzukiit:20181205211436p:plain

Azure上の関数を動かす

作成した関数を実行するURLは下記のような感じになります。
https://<作成したアプリ名>.azurewebsites.net/api/function1?name=onariomonprogram

ブラウザで実行してみると、成功!! f:id:tt-suzukiit:20181205210236p:plain

最後に

今回はVisual Studioから簡単なAzure Functionsの関数の作成、デプロイを行いました。 Visual Studioから作ることでAzure Functionsもソース管理、自動テストやCI/CDを組んだりできるようになるので、
今後、紹介していきたいと思います。

参照ページ

docs.microsoft.com