AWSでLinuxしか触ったことない人が、AWSでWindowsServerを利用するときに知らないと損すること

## はじめに

* AWSでLinuxばかりやってたんですがWindowsServerを触らないといけない機会が凄く増えててビビってます。
* WindowsServer利用するときも、まぁ大体Linuxと一緒なんでしょ！？と思ってたら火傷しますのでしっかりと抑えておきましょう。
* 他にもWindowsだと気をつけないといけない！なんてことがあればご指摘ください。

## ライセンスはどうなってるのか？押さえておこう。

* WindowsServerのライセンス
    * EC2の費用に含まれている。
    * OSにCALの料金が含まれているのでCALの購入は不要
* WindowsServerのライセンス持ち込みについて
    * 可能だが[占有ホスト](https://aws.amazon.com/jp/ec2/dedicated-hosts/)で実行する必要がある
* 以下の既存のマイクロソフトライセンスはAWS上に持ち込み可能。
    * 1サーバ1ライセンス、1プロセッサライセンス4コアまでの1インスタンスに対応
    * Exchange Server
    * SharePoint Server
    * SQLServer Enterpriseなど
* Officeのライセンスについて
    * ハードウェア占有インスタンス、占有ホストで利用可能
* その他ライセンスについて不明な点があれば[AWS と Microsoft に関するよくある質問 - ライセンシング](https://aws.amazon.com/jp/windows/faq/#licensing)を読んでおく。

## サポート＆トラブル

* [Windows インスタンスのトラブルシューティング](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/troubleshooting-windows-instances.html)を読んどく
* AWSがどんなサポートをしてくれるかについては、[Microsoft ソフトウェアに関する問題について、AWS はどのようなサポートを提供していますか?](https://aws.amazon.com/jp/windows/faq/#aws-support-ms)を読んでおこう。

## どのイメージを利用すればよいのか？

* EC2の画面から「パブリックイメージ」「所有者：Amazonイメージ」

Windows Server 2012 R2

* 「search：Windows_Server-2012-R2_RTM-」で検索する。
* 「search：Windows_Server-2012-R2_RTM-Japanese」で検索するとLocaleがJapaneseで設定済のものもあるのでこれを選んでおくと楽ですね。

WindowsServer2016

* 「search:Windows_Server-2016-Japanese」

WindowsServer2019

* 「search:Windows_Server-2019-Japanese」


![EC2 Management Console 2016-10-07 14-33-05.png](https://qiita-image-store.s3.amazonaws.com/0/57686/a0024352-9f0f-495e-092e-cd86b3020fa4.png)

* 最新のパッチが当たったAMIを公開してくれており、10月5日現在だと6月以前のAMIは無くなっていました。どうしても元のAMIをとっておきたい場合はプライベートイメージとして保管しておく必要がありそう。（が、、、そういうケースはあるんだろうか）

>AWS は、Microsoft の火曜パッチ（毎月第 2 火曜日）の 5 営業日以内に、更新されパッチが全面的に適用された Windows AMI を提供します。

* 新しいAMIがリリースされた時や以前のAMIが非公開になった時に通知をAmazonSNSで受けることができるようです。Subscriptionの設定で以下のARNを設定すればよいようです。

```
arn:aws:sns:us-east-1:801119661308:ec2-windows-ami-update
arn:aws:sns:us-east-1:801119661308:ec2-windows-ami-private
```

* 追加で含まれるもの
    * EC2Config
    * 準仮想化ドライバ
    * AWS Tools for Windows PowerShell
    * AWS Cloudformationヘルパースクリプト

* 参考
    * [Amazon マシンイメージ（AMI）
](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/AMIs.html)
    * [Amazon マシンイメージ（AMI） » AWS Windows AMI バージョン履歴](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/windows-ami-version-history.html#windows-ami-versions)


## インストールメディアは使えるのか？

* 使える。
* マネジメントコンソールでスナップショットを開いて以下の条件で検索
    * パブリックスナップショットを選択
    * 所有者：Amazonイメージ
    * 説明：Windows 2012 R2
* あとはボリュームの作成してWindowsServerにAttachすれば利用できる

## どうやってWindowsServerに接続するのか？

* RDPで接続する。パスワードはManagementConsoleからパスワードの取得を行うことで取得できる。
* インスタンス起動後すぐに取得できるわけではなく、「あとN分後に取得できます。」のメッセージが出てくる。
* これは後述するEC2Configがパスワードの初期化を行っているから。

## 拡張ネットワーキングは有効にしておこう

* C3,C4,D2,I2,M4,R3インスタンスは拡張ネットワーキング機能を利用可能
    * [拡張ネットワーキングとは？](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/enhanced-networking.html)
* WindowsServer2012R2
    * デフォルトで有効になっているのでインスタンスタイプを選択しておくだけで良いがドライバを最新バージョンにアップグレードすることが推奨されている。
    * [Intel NetworkAdapter Driver for WindowsServer 2012R2](https://downloadcenter.intel.com/download/23073/Network-Adapter-Driver-for-Windows-Server-2012-R2-)
* WindowsServer2012R2 **以外**
* どちらのOSであっても有効化されていることをCLIを使って確認しておくこと
    * [VPC 内の Windows インスタンスにおける Intel 82599 VF インターフェイスを使用した拡張ネットワーキングの有効化](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/sriov-networking.html)

## [インスタンスの自動復旧設定をしておこう](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-recover.html)

* Windowsに限った話ではないが、AutoRecoveryは設定しておく。やっといて損しない。
* AutoRecoveryはシステムステータスチェックが失敗した場合（ネットワークとか電源とかホスト側の問題でこちらではどうしようもない問題）に自動で復旧してくれる機能で無料で利用できる。
* 利用条件
   * インスタンスタイプはC3、C4、M3、M4、R3、T2、および X1
   * VPC内で動作しEBS-Backedとなっていること
   * 占有インスタンスではないこと
* 参考
    * [【AWS発表】Amazon EC2の自動リカバリ(Auto Recovery)機能](http://aws.typepad.com/aws_japan/2015/01/new-auto-recovery-for-amazon-ec2.html)

## AutoHealingの設定

* これもWindowsに限った話ではないが1台構成でもAutoHealingの設定をしておくことを検討しておく。
* AutoHealingとはAutoScalingGroupの起動数をmin:N,max:Nにしておくことで常にN台起動する状態を作ることを言います。
* 詳しくは別記事にしますが簡単に触れておく。
* AutoScalingGroupを利用する場合
  * トリガーはStateがRunningじゃなくなったとき。
  * PrivateIPが変わってしまうので上位にELBを挟むなどの考慮が必要。
  * CloudWatch→SNS→Lambda→AutoScalingGroupをUnHealthyにすることで細かい障害の検知などが可能になる。
* OptsWorksを利用する場合
  * トリガーはOptsWorksAgentがOptsWorksに通信できなくなったとき。
  * PrivateIPを変更することなくAutoHealingが動かせるが、AutoScalingGroupのような細かい制御は無理

## EC2Configの役割について知っておく

* EC2ConfigはWindows版Cloud-initみたいなものです。EC2Configがやってくれる役割については認識しておこう。
* AWSが提供するWindowsServerイメージを利用すると既にインストール済になっています。
``C:\Program Files\Amazon\Ec2ConfigService¥Ec2ConfigServiceSettings.exe``
* サービスも自動で起動しているので特に何かしておく必要はありません。
* こんなことをやってくれます。
    * [EC2Config サービスを使用した Windows インスタンスの設定](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html)

```
* 初回起動時のタスクには以下のものがあります。
    * 管理者アカウントに、ランダムに生成した暗号化パスワードを設定する
    * リモートデスクトップに使用されるホスト証明書を生成しインストールする
    * オペレーティングシステムパーティションを動的に拡張して、未使用の領域が含まれるようにします。
    * 指定されたユーザーデータ（および、インストールされていれば Cloud-Init）を実行します。
* EC2Config は、インスタンスが起動するたびに次のタスクを実行します。
    * 16 進数表記のプライベート IP アドレスと一致するようにコンピュータのホスト名を変更する（このタスクはデフォルトでは無効になっているので、このタスクを有効にしてインスタンスの起動時に実行する必要があります）。
    * key management server （KMS）を構成し、Windows アクティベーションのステータスを確認して、必要に応じて Windows のアクティベーションを行う。
    * すべての Amazon EBS ボリュームおよびインスタンスストアボリュームをマウントし、ボリューム名をドライブ文字にマップします。
    * イベントログエントリをコンソールに出力し、トラブルシューティングに役立てる（このタスクはデフォルトでは無効になっているので、このタスクを有効にしてインスタンスの起動時に実行する必要があります）。
    * コンソールに Windows の準備が完了した旨の通知を出力する
    * 複数の NIC がアタッチされているとき、プライマリネットワークアダプタにカスタムルートを追加して、IP アドレス 169.254.169.250、169.254.169.251、および 169.254.169.254 を有効にする。これらのアドレスは Windows ライセンス認証が使用し、またユーザーがインスタンスのメタデータにアクセスする際にも使用します。
* EC2Config は、ユーザーがログインするたびに以下のタスクを実行します。
    * デスクトップ背景に壁紙情報を表示する
```

* 他の用途については以降で説明します。

## AMIの作成方法は２パターンあることを知っておく

1. マネージメントコンソールやCLIからAMIの作成を行う
2. EC2ConfigからAMIを作成する

* 所謂システムバックアップを取得する場合は1を利用すれば良い。
* EC2ConfigからAMIを作成する理由は、展開用のイメージを作るときです。実行するとセキュリティ識別子（SID）、コンピュータ名、イベントログなど固有の情報が削除され、インスタンスが停止します。停止した状態でコンソールやCLIからイメージを作成すればインスタンス固有の情報が排除されたAMIの作成ができます。
* 作成の方法については[Sysprep を使って標準の Amazon マシンイメージを作成します。](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ami-create-standard.html)を参考にしてください。

* 参考
    * [マシンSIDの重複神話](https://technet.microsoft.com/ja-jp/windows/mark_12.aspx)

## AWS Diagnostics for Microsoft Windows Serverは入れとけ

* このツールを使うとWindowsServer上から様々な情報を収集し、AWSテクニカルサポートに問い合わせるときに情報を集めるのが非常に楽になるということと、既知の問題に引っかかっていないかを検査してくれるらしいです。素晴らしい。
* いざサポートに問い合わせる必要が出た時にも慌てないようにダウンロードしておいておき、動くことも確認しておくこと！
* 集められる情報

```
IP アドレスとルートテーブルなどのネットワーク情報
ドメインとコンピュータ名
ライセンスの状態、Key Management Server (KMS) の構成などのアクティベーション設定
現在の時刻と時間帯などの時間設定
インスタンス上にインストールされたドライバ
セキュリティグループのルールに沿った Windows ファイアウォールの設定
インストールされた更新
Windows が 1 週間以内にクラッシュした場合のミニダンプファイル
```
* 分析ルール

```
アクティベーションステータスと KMS 設定のチェック
メタデータと KMS アクセスに対する適切なルートテーブルエントリのチェック
セキュリティグループルールと Windows ファイアウォールルールの比較
PV ドライバのバージョン確認（Redhat または Citrix）
RealTimesUniversal レジストリキーが設定されているかの確認
複数の NIC を使用している場合のデフォルトゲートウェイ設定
ミニダンプファイルのコードのバグチェック
```

* 動かすのは非常に簡単で、[こちらからダウンロード](https://aws.amazon.com/jp/windows/resources/aws-diagnostics/)して、exeをクリックするだけです。credentialの入力を求められるますが、予めEC2にReadonlyのRoleを設定しておき利用すると良いでしょう。

![10.0.0.117  2016-10-07 15-08-35.png](https://qiita-image-store.s3.amazonaws.com/0/57686/67feb6e9-f1ff-51a5-2dae-13ce0b54b5ea.png)

* 「OpenReport」をクリックするとテキストでレポートが出力されます。Windowsがライセンスされてるか。SecurityGroupの設定とFirewallの設定が合致しているかなどです。
* 収集されたデータは実行ディレクトリと同じディレクトリに出力されていました。
* ![10.0.0.117  2016-10-07 15-14-48.png](https://qiita-image-store.s3.amazonaws.com/0/57686/fe70b763-7da6-ab88-f36a-d8f82e816814.png)

* 参考
    * [AWS Diagnostics for Windows Server - Beta](http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/Windows-Server-Diagnostics.html)

## 監視はどうやる？(Cloudwatch）

* プロセス、パフォーマンス
    * パフォーマンスカウンタで取得したデータをCloudWatchにメトリクスとして登録することが出来ます。パフォーマンスカウンタを利用すると大体のデータは取れるのでpowershellでcloudwatchにput-metricsする必要は無いです。
    * ただし、すべてカスタムメトリクスになるのでガンガン登録するとそれだけコストがかかります。監視するものはカスタムメトリクスとして登録、後々みれれば良いものはパフォーマンスカウンタとして取得しておくよう選別しておこう。
* ログ
    * イベントログ含め、任意のログデータをEC2Configを利用することでCloudWatchLogsに取り込むことが出来ます。
* 監視
    * CloudWatchのカスタムメトリクス、CloudWatchLogsに取り込めればこちらのものですね。Cloudwatchの標準機能を使って通知まで実現出来そうですね。

* パフォーマンスカウンタのデータや、ログをCloudWatch,CloudWatchLogsに取り込む手順は以下の通りです。

### 共通の設定（CloudWatch Logs の認証情報、リージョン、ロググループ、ログストリームを設定）

* EC2インスタンスにCloudwatch,CloudwatchLogsにアクセスするためのロールを付与します。

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "cloudwatch:*",
        "logs:*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

* EC2Configの設定を開きます。

``C:¥Program Files¥Amazon¥Ec2ConfigService¥Ec2ConfigServiceSettings.exe``

* [Cloudwatch Logs] - [Enable CloudWatchLogs Integration]にチェックを入れます。

![10.0.0.117  2016-10-07 15-27-36.png](https://qiita-image-store.s3.amazonaws.com/0/57686/248d9425-0939-7a63-3e99-20250142a50c.png)

* 下記の設定ファイル内のリージョンを変更しておきます。今回は東京（ap-northeast-1)にしてあります。
* ロールの設定が行われている場合は、AccessKey,SecretKeyは無視されるので空のままで良いです。

``C:\Program Files\Amazon\Ec2ConfigService\Settings\AWS.EC2.Windows.CloudWatch.json``

```AWS.EC2.Windows.CloudWatch.json
            {
                "Id": "CloudWatchLogs",
                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "AccessKey": "",
                    "SecretKey": "",
                    "Region": "ap-northeast-1",
                    "LogGroup": "Default-Log-Group",
                    "LogStream": "{instance_id}"
                }
            },
            {
                "Id": "CloudWatch",
                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatch.CloudWatchOutputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": 
                {
                    "AccessKey": "",
                    "SecretKey": "",
                    "Region": "ap-northeast-1",
                    "NameSpace": "Windows/Default"
                }
            }
```

* ここまでで事前の設定はおしまいです。

### イベントログをCloudWatchLogsでみえるようにしてみます

* このあたりがイベントログの設定になります。

```AWS.EC2.Windows.CloudWatch.json
{
    "EngineConfiguration": {
        "PollInterval": "00:00:15",
        "Components": [
            {
                "Id": "ApplicationEventLog",
                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "LogName": "Application",
                    "Levels": "1"
                }
            },
            {
                "Id": "SystemEventLog",
                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "LogName": "System",
                    "Levels": "7"
                }
            },
            {
                "Id": "SecurityEventLog",
                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                "LogName": "Security",
                "Levels": "7"
                }
            },
```

* イベントログをCloudWatchLogsに出力するには、IdをFlows加えてあげれば良いです。今回はSecurityEventLogを出力するように追記してみました。

```AWS.EC2.Windows.CloudWatch.json
        "Flows": {
            "Flows": 
            [
                "(ApplicationEventLog,SecurityEventLog,SystemEventLog),CloudWatchLogs"
            ]
        }
```

* EC2Configを再起動して少し待つとCloudWatchLogsにログが出力されました。

![CloudWatch Management Console 2016-10-07 16-52-29.png](https://qiita-image-store.s3.amazonaws.com/0/57686/11428d2a-6db9-5c5e-b56e-4b4f9d3503b2.png)

### パフォーマンスカウンタのデータをCloudWatchカスタムメトリクスに表示してみよう

* この設定はAvailable MBytesをパフォーマンスカウンタから抽出してCloudWatchのカスタムメトリクスに名前空間Windows/Defaultの中にMemoryというメトリクスを追加しています。

```AWS.EC2.Windows.CloudWatch.抜粋.json
            {
                "Id": "PerformanceCounter",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "Available MBytes",
                    "InstanceName": "",
                    "MetricName": "Memory",
                    "Unit": "Megabytes",
                    "DimensionName": "",
                    "DimensionValue": ""
                }
            },
・・・
            {
                "Id": "CloudWatch",
                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatch.CloudWatchOutputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": 
                {
                    "AccessKey": "",
                    "SecretKey": "",
                    "Region": "ap-northeast-1",
                    "NameSpace": "Windows/Default"
                }
            }
・・・
        "Flows": {
            "Flows": 
            [
                "(ApplicationEventLog,SecurityEventLog,SystemEventLog),CloudWatchLogs",
                "(PerformanceCounter),CloudWatch"
            ]
        }
```

* これも設定後再起動すると、このようにメモリがカスタムメトリクスに表示できます。

![CloudWatch Management Console 2016-10-07 17-00-16.png](https://qiita-image-store.s3.amazonaws.com/0/57686/982d19fe-ae9a-b3ee-098f-4473c307e06b.png)

* いやー便利ですね。

### CloudWatchのメトリクスデータの保管

* CloudWatchのメトリクスは2週間経つと自動で消えてしまいます。
* 2週間より大きい期間のデータの保管が必要な場合は、定期的にAPIを使ってローカルに落としておくなどの工夫が必要。

### CloudWatchLogsの保管期間を決めておこう

* CloudWatchLogsも勿論お金が掛かります。
* CloudWatchLogsのログの保管期間はデフォルトで無制限なので変更しておきましょう。
* 参考
    * [ログ期間の変更](http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/SettingLogRetention.html)

## RunCommandの活用検討及び利用準備はしておく。

* RunCommandはWindows,Linux共にEC2にログインせずともコマンドが実行できる機能
* Windowsの場合はEc2Configが入っているのでOS側にエージェントのインストールは不要。
* Javaのアプリケーションを運用していた場合、事前に準備さえしておけばJavaのThreadDumpもOSにログインしないで実行することができるわけです。

|デフォルトで利用できるRunCommand|
|:-----------------|
|AWS-JoinDirectoryServiceDomain to join an AWS Directory|
|AWS-RunPowerShellScript to run PowerShell commands or scripts|
|AWS-UpdateEC2Config to update the EC2Config service|
|AWS-ConfigureWindowsUpdate to configure Windows Update settings|
|AWS-InstallApplication to install, repair, or uninstall software using an MSI package|
|AWS-InstallPowerShellModule to install PowerShell modules|
|AWS-ConfigureCloudWatch to configure Amazon CloudWatch Logs to monitor applications and systems|
|AWS-ListWindowsInventory to collect information about an EC2 instance running in Windows.|
|AWS-FindWindowsUpdates to scan an instance and determines which updates are missing.|
|AWS-InstallMissingWindowsUpdates to install missing updates on your EC2 instance.|
|AWS-InstallSpecificWindowsUpdates to install one or more specific updates.|

* 事前に利用できないかは検討しておこう。利用しない場合でも動かせるように準備はしておいた方が良いと思う。
* RunCommandが利用できる条件は「[RunCommandの前提条件](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/remote-commands-prereq.html)」を参照。

## おわりに

* どうでしょうか。結構色々ありますね。何かあったときに慌てないようにNATやロールの設定は予め考えておきたいですね。