ARMテンプレートでMicrosoft Azure上にクラウドVNFを自動化導入

#はじめに
##### <font color="DeepPink">!! Merry Christmas !!</font>
本日は「待降節」最終日＝アドベントカレンダーラストの日となりました。
この記事はシスコの同志による <font color="DarkSlateBlue"><B>Cisco Systems Japan Advent Calendar 2018</B></font> の 25 日目として投稿しました。無事に完走できて良かったと思います。

<B>2017年版</B>: https://qiita.com/advent-calendar/2017/cisco
<B>2018年版</B>: https://qiita.com/advent-calendar/2018/cisco

約半年ほど前に Cisco の販社様向けセミナーにて、主に AWS, Azure を中心としたパブリック上の NG-Firewall, NG-IPS, VPN のネットワークデザインに関するセッションを担当する機会がありました。その時紹介したセッション内容の中で時間的余裕が無く、一つだけ実環境で試せなかったテーマが<B>テンプレート導入</B>でした。

このエントリで取り上げるテーマは
「 <B>Microsoft Azure 上で VNF として Cisco ASAv のコンピュートリソースを ARM Template から自動化導入する方法</B>を試してみる」
ということになります。


# クラウド上におけるネットワークデザインのジレンマ
クラウド上にネットワークを構成する要件において現時点での客観的背景と所感を少しだけまとめます。
![スクリーンショット 2018-12-23 20.54.44.png](https://qiita-image-store.s3.amazonaws.com/0/311200/8c0975b7-8201-31d9-7c9a-b4ab0f30643d.png)
[記事1](https://www.twst.com/update/gartner-inc-gartner-forecasts-worldwide-public-cloud-revenue-to-grow-21-4-percent-in-2018/), [記事2](https://www.dailyhostnews.com/worldwide-public-cloud-market-to-hit-186-4-billion-gartner/), [記事3](https://hostingjournalist.com/iaas-hosting/gartner-hyperscale-iaas-cloud-market-dominance-climbs-70-percent-2018/)


今年の4月あたりのパブリッククラウドに対する象徴的な記事だと思います。2017年の市場規模15兆円から18兆円に拡大、客観的な見方として、サーバ保有規模が数十万台〜数百万台を保有したソフトウェアもハードウェアも自前で開発・調達する <B>Amazon, Microsoft, Google のようなハイパースケールクラウドベンダーが既存、今後参入の90%の IaaS ベンダーを排除していく</B>ことになるだろう、ということだそうです。我々はますますAWS, Azure, GCPのようなクラウド基盤におけるネットワーキング技術を勉強しないといけません。

このような状況の中、クラウド上で展開する Firewall やルータをどうスケールアウトしていくか、クラウド上のネットワークコンポーネント障害時の自動復旧に備えるデザインはどうあるべきか、AWS ELB, Azure LB 等クラウドネイティブなコンポーネントとの組合せはどうするべきか、などの物理ネットワークで当たり前になるデザイン議論は企業内導入や商用化検討も含め、まだまだといったところ、ようやく始まってきたと感じています。

ハイパースケールクラウドにおけるネットワーキングやネットワークデザイン最適化検討のため、抑えるべき前提事項を以下に整理します。

#####1. クラウドネイティブのネットワークコンポーネントとその操作方法の理解
これまでハードウェアを中心に実装を担当する技術者であったとしても、ハードウェアからデカップリングされたソフトウェア機能をオンプレミス仮想化環境で扱う技術、SDN技術はベースラインのノウハウとなりつつあります。このようにVMW vSphere, vCenter, OpenStack KVM, ovs, dvs, 仮想スイッチの理解と扱いが当たり前になったと同様に、クラウド上でネットワークを構成する場合、クラウドネイティブのネットワークコンポーネントと、ポータル/ダッシュボードによるこれらの操作方法の理解が必要になります。VPC, VNET, UDR, Route Table, NSG, SG, Availability Setって何？の知識、特性の理解がどうしても必要になります。

#####2. クラウドネイティブのネットワーキング技術の理解（L2 が存在しない当たり前の世界）
　仮想L2レイヤーが存在するプライベートクラウド仮想化環境において、ルータやFirewallのような仮想アプライアンス/VNFは物理コンポーネントと同様にそれぞれの接続性を明確に意識した設計と導入が必要でした。TCP/IP, L2/L3の当たり前を理解しているネットワーク技術者にとって、Azure UDR (ユーザ定義ルート) は一瞬でも摩訶不思議な概念であると感じてしまいます。
　L2, ブロードキャストドメイン, ARPを意識しないネットワークであるため、例えば物理機器で実現できたサブセカンドのFailover機能の実装が難しく、こうした反面、導入する仮想アプライアンス/VNFとクラウド独自のネットワーキング、インフラへのプログラミング技術と統合した実装があることを理解する必要があります。

#####3. クラウドネイティブのネットワークコンポーネントは信頼を前提に考える
　信頼性向上のため、物理環境ではスイッチ、ルータ、インターフェースの冗長化、プライベートクラウドでは仮想化基盤の冗長化の方式を検討することは最低限の要求項目となっていました。クラウドにおいては前述のとおり、それぞれ独自の機能について冗長化、スケーラビリティのサービス要件を受け入れる必要があります。



# Microsoft Azure - ARM Template 概要
<B>前置きが長くなってしまいましたが、今回の主テーマに話を戻します。</B>

これまでのハードウェア、物理ネットワーク機器、物理アプライアンス用いアプリケーションインフラストラクチャを構築する場合のステップとして、梱包されたダンボールから製品を取り出し、ラックマウントを行い、コンソールケーブルをセットアップ用 PC に接続、ネットワーク機器にはトランシーバを接続し各機器をネットワークケーブルで接続しルーティング設定、コンピュートノードのためにストレージの用意を行います。これは非常に理解しやすいインフラの初期セットアップステップです。

パブリッククラウド上ではこういったノードの基本設定のための相互接続そのもの、クラウドインフラに統合されたサブネットのルーティング、仮想マシンにアタッチするためのストレージ、ストレージを構成するためのアカウント等をリソースとして宣言し、リソースグループとして関連付け、運用を行うことができます。
いわば、<B>ネットワークケーブル、トランシーバ、管理用 PC、管理者や作業者そのものもパブリッククラウド上ではリソースとして扱われるイメージ</B>です。

こうして作られたインフラ上のコンポーネントで構成されたリソースのグループはパブリッククラウド上で<B>テンプレート</B>として扱うことができ、予め構成されたセットが再導入のプロセスを間違えることなく横展開ができるというメリットがあります。物理環境に当てはめると、もうひとつシステムのポッドが必要な場合、ラッキングからケーブリング、機器初期セットアップまで完全自動化されてやってくれるイメージです。

こうして作成されたテンプレートはシステムスケールアウト、システムバックアップ、テスト開発環境への利用、案件顧客、ビジネスパートナーとの共有といった利用例が考えられます。

以下, リソース, リソースグループ, テンプレートについてMicrosoft Docsから引用させていただきます。


- <I><B>リソース</B>
 - <font color="DimGray">Azure を通じて管理できる要素。 一般的なリソースとしては、仮想マシン、ストレージ アカウント、Web アプリ、データベース、仮想ネットワークなどがありますが、他にもさまざまなリソースが存在します。
- <I><B>リソース グループ</B>
  - <font color="DimGray">Azure ソリューションの関連するリソースを保持するコンテナー。 リソース グループには、ソリューションのすべてのリソースか、グループとして管理したいリソースのみを含めることができます。
- <I><B>Resource Manager テンプレート</B> 
 - <font color="DimGray">リソース グループへのデプロイ対象となるリソースを定義する JavaScript Object Notation (JSON) ファイルです。 デプロイ対象リソース間の依存関係も、このテンプレートによって定義されます。 このテンプレートを使えば、リソースを一貫性のある形で繰り返しデプロイできます。

### Azure Resource Manager (ARM)  フォーマット
 Microsoft Azure 上のテンプレート機能として、Azure Portal (GUI) 以外からでも Power Shell, Cloud Shell, REST API による包括的な導入方法をサポートする<B>宣言型構文 JSON スクリプト</B>ということです。

```json
{
　"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "resources": []
}
```

# 目標と確認項目
Cisco ASAv を利用します。ARM テンプレートを利用することにより、例えば 

- <B>3-Tier Web アプリ（Web/アプリ/DBサーバ + ASAv）の一括構成</B>
- <B>マルチ ASAv の Azure Availability Set + Azure LB 利用による HA 構成</B>

といった拡張アプリケーションシステムをリソースグループテンプレートから1クリックで構成することができますが、今回はテンプレート対象リソースとしてシンプルな単一のASAvを対象としています。これまでの話の流れとして、

*「あれ？AWSのテンプレート機能は？」*

という当たり前の疑問があるかもしれません。現時点ではAWS版テンプレート機能の<B>CloudFormation</B>はASAv on AWSで正式サポート対象となっていません。そのためMicrosoft Azure環境でのテンプレート機能から試すことにしました。


以下、今回の目標とそのステップです。

<B>1. <font color="DarkSlateBlue">Cisco ASAv 用 ARM テンプレート作成</B></font>
<B>2. <font color="DarkSlateBlue">作成テンプレートから Cisco ASAv の導入テスト</B></font>
<B>3. <font color="DarkSlateBlue">Azure Cloud Shell からテンプレート導入</B></font>

# ステップ
#### 1. <font color="DarkSlateBlue">Cisco ASAv 用 ARM テンプレート作成</font>
Azure上に作成されたすべてのリソースは相互関係を持つ他のリソースとともにテンプレートとして自動的にコード化されていきます。今回汎用的なARMテンプレート作成することも一つの目的ですが実はポータルから展開されたすべてのリソースはこのように、ARMテンプレートの素が勝手に生成されている、ということになります。自動的に作成されたテンプレートがそのまま導入できるか、どれだけ汎用的であるかについて確認をする必要がありました。

まずはポータルから動く状態のASAvをデプロイし、一つのASAvにどれだけのリソースが関連するかを確認し、無事に展開されたASAvリソースから自動生成されたテンプレートを確認し編集します。

- ASAvをポータルからデプロイ
 - "<B>すべてのサービス</B>" から "<B>marketplace</B>" を検索
 - "<B>すべてを検索</B>" から "<B>Cisco ASAv</B>" を検索
 - "<B>Cisco ASAv - BYOL 4 NIC</B>" を選択し "<B>作成</B>" をクリック
 - 4ステップのWizardから必要情報を入力し, 最後に "<B>Buy</B>"

    Azureを初めて利用する場合でも、導入するASAvの必要な関連リソースはすべてWizardの中で作成できます。（簡単なので参照スクリーンショットは割愛）

    ASAv 仮想マシンの他に<B>VNET, NIC x 4</B>, <B>Security Group</B>, <B>Route Table x 4</B> , <B>PublicIP</B>, <B>Storage Account</B> が作成されています。これらが関連するASAv 仮想マシンに必要な最低限な関連リソースです。
![スクリーンショット 2018-12-24 14.36.08.png](https://qiita-image-store.s3.amazonaws.com/0/311200/be7a83e1-40fd-b8dd-a8d3-8deb852060f7.png)

    リソースから<B>Public IP Address</B>にアサインされた実際のIPアドレスを確認し、仮想マシンの1st Interfaceとしてアサイン、アタッチされたこのIPアドレスにてマネージメントインターフェースへの接続確認を行います。

```bash

linux:~ $ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-dss shkimura@40.115.165.87
shkimura@40.115.165.87's password: 
```

補足ですが、ASAv on Azure, ASAv on AWSもインターフェースは4つが固定、"追加"や、使わなくても"削除"、することはできません。Azure Portal上ではDeploy時に作成した4つのインターフェースリソースにIP addressがアサインされていますが、初期導入時のASAvでは1stインターフェースである<B>m0/0</B>のみ`no shut`状態でDeploy時に指定したIPアドレスレンジでのアドレスが<B>dhcp</B>としてアサインされています。これは正しい状態であり、その他のインターフェースでは初期初期設定として、`nameif`, `security-level`, を指定し、`ip address dhcp setroute`, `no shut`することによりAzureポータル上でその他 ASAv 用 NIC にアサインされている IP アドレスが実際にアサインされることになります。

`sh ip`

```
User shkimura logged in to ASAv-01
Logins over the last 5 days: 1.  
Failed logins since the last login: 0.  
Type help or '?' for a list of available commands.
ASAv-01>
ASAv-01> en
Password: 
ASAv-01# sh ip
System IP Addresses:
Interface                Name                   IP address      Subnet mask     Method 
Management0/0            management             10.0.0.4        255.255.255.0   DHCP  
Current IP Addresses:
Interface                Name                   IP address      Subnet mask     Method 
Management0/0            management             10.0.0.4        255.255.255.0   DHCP  
ASAv-01# 
```

作成された ASAv 仮想マシンのリソーステンプレートを確認しテンプレート導入をテストしながらスクリプトを編集します。

- 新規テンプレートの作成
 - "<B>すべてのリソース</B>" から "<B>ASAv 仮想マシン</B>" を選択、"<B>Automation スクリプト</B>" を選択、テンプレート内すべてを<B>コピー</B>
 - "<B>すべてのリソース</B>" から "<B>テンプレート</B>" を検索、"<B>テンプレート</B>" を選択、"<B>＋追加</B>" を選択、NameとDescriptionを指定し、テンプレートを<B>ペースト</B>、"<B>保存</B>"
![スクリーンショット 2018-12-24 15.06.37.png](https://qiita-image-store.s3.amazonaws.com/0/311200/780f97c1-4bb5-1e8b-23c5-0f107838a29b.png)

- 保存したテンプレートを編集しテンプレート導入をテスト
テンプレート導入のテストを行いながら最終的にスクリプト内の以下の項目を編集しました。基本的にはリソースID、Macアドレス等マニュアルデプロイ時にリソースにアサインされた固有、固定のパラメータの削除、その他不要パラメータの削除、汎用的な関数名への変更となります。
 - 削除: `comments`, `resourceGuid`, `etag`, `macaddress`, `provisionigState`, `piblicIPaddress`
 - 追加: `adminPassword`
 　
- Github リポジトリへ保存
[Azure Resource Manager QuickStart Templates](https://github.com/Azure/azure-quickstart-templates)
[Azure Resource Manager QuickStart Templates - Contribution Guide](https://github.com/Azure/azure-quickstart-templates/tree/master/1-CONTRIBUTION-GUIDE)
このリポジトリにはコミュニティベースで作成された多数のテンプレートとデプロイ方法のチュートリアル情報にアクセスできるとともに、作成したテンプレートを公開する時のファイル、フォルダネーミング等約束事のガイドライン（コントリビューションガイド）、ベストプラクティスが公開されています。（なるべく）このガイドラインに従い編集していきます。以下ガイドラインのサマリです。
 - 作成するファイル、フォルダはREADME.mdを除いて小文字使用（Azure Quick Template Repoを使う場合、100, 101から始まるフォルダ名をつける）
 - デプロイメントテンプレート本体ファイル名：<B>azuredeploy.json</B>
 - パラメータ格納用ファイル名：<B>azuredeploy.parameters.json</B>
 - パラメータはデプロイメントテンプレートに含めない
 - メタデータ用ファイル名：<B>metadata.json</B>
 - README.mdに ![deploytoazure.png](https://qiita-image-store.s3.amazonaws.com/0/311200/2ab2911b-be94-99f3-ec0c-22705b1d8c7e.png), ![visualizebutton.png](https://qiita-image-store.s3.amazonaws.com/0/311200/17383252-7868-3978-a55e-cd827ad81a2d.png)をつける
 - README.mdサンプルがダウンロードできる（ボタンアイコンのダウンロードサンプルも含まれる）

以下に保存しました。
https://github.com/sig666/asav-test-template
　![スクリーンショット 2018-12-24 16.12.12.png](https://qiita-image-store.s3.amazonaws.com/0/311200/5bb9b9ee-7b99-d389-5400-c9c0fdc8f4c1.png)


#### 2. <font color="DarkSlateBlue">作成テンプレートから Cisco ASAv の導入テスト</font>
Azureポータルからテンプレート導入を行います。

- 作成されたテンプレートを選択し、"<B>展開</B>"を選択
![スクリーンショット 2018-12-24 17.36.01.png](https://qiita-image-store.s3.amazonaws.com/0/311200/2ad14e9b-6ea1-06ad-b211-7ee56b5eaf97.png)
- テンプレート内で指定したパラメータをレビューし、"<B>Buy</B>"
![スクリーンショット 2018-12-24 17.38.32.png](https://qiita-image-store.s3.amazonaws.com/0/311200/4a4f0952-c201-b5c3-848e-526ebb9c058e.png)
- 進行中のDeploymentステータスを確認するとリソースの作成ステータスが確認できます。
![スクリーンショット 2018-12-24 17.40.37.png](https://qiita-image-store.s3.amazonaws.com/0/311200/f6fe0883-3478-9cb3-b1d9-96c5e74a5a4d.png)
- およそ6分ほどですべてのDeployが完了しました。

#### 3. <font color="DarkSlateBlue">Azure Cloud Shell からテンプレート導入</font>
Azure Cloud ShellからAzure PowerShellを使い、Github上の外部レポジトリに保存された作成したテンプレートからの導入手順です。 Cloud Shellを利用するStorage Accountのclouddriveにテンプレートをロードし`-TemplateUri`の指定による導入も可能です。Azure Cloud ShellではPowerShellの他にBashがサポートされています。

[Azure Cloud Shell](https://shell.azure.com)にアクセスします。
`https://shell.azure.com`
初期利用時にはCloud Shell用のStorage AccountがResource Groupとともに作成されます。

```powershell:shell.azure.com

Requesting a Cloud Shell.Succeeded.
Connecting terminal...

Welcome to Azure Cloud Shell

Type "az" to use Azure CLI 2.0
Type "help" to learn about Cloud Shell

VERBOSE: Authenticating to Azure ...
VERBOSE: Building your Azure drive ...
Azure:/
```

`Connect-AzureRmAccount`
Azure Accountに接続します。

```powershell:shell.azure.com
PS Azure:\> Connect-AzureRmAccount
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code H*******R to authenticate.
```
Azure Cloud ShellによるDeployment実行にあたり、このコマンドを利用するブラウザでAzure Portalにログインしているアカウントとのシングルサインオン認証を行います。
![スクリーンショット 2018-12-23 23.50.51.png](https://qiita-image-store.s3.amazonaws.com/0/311200/1a43d509-6034-6086-2c98-b4a64cd54cf1.png)


`Select-AzureRmSubscription -SubscriptionName <"yourSubscriptionName">`
サブスクリプションを選択します。

```powershell:shell.azure.com
PS Azure:\> Select-AzureRmSubscription -SubscriptionName Pay-As-You-Go

Name                                     Account                      SubscriptionName             Environment                  TenantId
----                                     -------                      ----------------             -----------                  --------
Pay-As-You-Go (5b2cba5f-2414-4680-842... shkimura@gmail.com           Pay-As-You-Go                AzureCloud                   753849bd-acee-4855-832b-a...
```

`New-AzureRmResourceGroupDeployment -ResourceGroupName <"yourResourceGroupName"> -TemplateUri <"yourExternalRepositoryURI">`
展開するリソースグループを指定し、Github上のRawフォーマット`azuredeploy.json`を指定します。

```powershell:shell.azure.com
New-AzureRmResourceGroupDeployment -ResourceGroupName RG-01 -TemplateUri https://raw.githubusercontent.com/sig666/asav-test-template/master/azuredeploy.json`
```

# 最後に
今回作成したCisco ASAv テスト導入のARMテンプレートは、環境にふれる時間がある限りまだまだテスト＆更新しています。
https://github.com/sig666/asav-test-template
まずは初期ステップとしてネットワーク（セキュリティ）コンポーネントのテンプレート導入の基本を理解する、加えてAzureそのものに慣れるというところでひとつのリファレンスソースとなれば幸いです。

# 参照
[1] Azure Resource Manager の概要
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-overview
[2] Azure Resource Manager QuickStart Templates
https://github.com/Azure/azure-quickstart-templates
[3] Azure Resource Manager QuickStart Templates - Contribution Guide
https://github.com/Azure/azure-quickstart-templates/tree/master/1-CONTRIBUTION-GUIDE
[4] Define resources in Azure Resource Manager templates
https://docs.microsoft.com/en-us/azure/templates/
[5] Azure Quickstart Templates
https://azure.microsoft.com/en-us/resources/templates/


## おまけ
シスコは次世代セキュリティ人材育成に向けてサイバーセキュリティスカラシップを創設しています。
学生向け、受講費用無料のこのプログラムの一部オンラインコースは学生以外の方にも広く活用いただけることになりました。興味のある方は、詳しくは[こちら](https://www.cisco.com/c/m/ja_jp/about/security-scholarship.html)をご参照ください。