CloudFormationでvCenter Serverを起動する

# はじめに
検証でたまに環境が必要になることがあるので、vCenter Server 5.5をEC2インスタンスにインストールするCloudFormationテンプレートを作成しました。
[AWS Management Portal for vCenter](http://aws.amazon.com/jp/ec2/vcenter-portal/) の検証環境を作るときなどにおすすめです。

なお、テンプレートは東京リージョンで動作確認をしています。
（需要があるのかわかりませんが）他リージョンでは未確認ですのでご注意ください。

# 使い方

##事前準備
vCenter Server のインストールメディアをコピーした EBS Snapshotを準備しておきます。
VMware社のWebサイトからISOを取得し、EC2インスタンス上などでコピーしてください。
Windows Server 2012以降であればISOを直接マウントできるので作業が捗ります。

##使用手順
次のセクションのCloudFormationテンプレートをコピーして適当なファイルに保存してください。
Management Console からテンプレートファイルを指定するとそのままCloudFormationスタックとしてvCenter ServerのインストールされたWindows Server 2012 R2が展開されます。
スタック作成時のパラメータとして以下の情報を指定してください。

- Windows Server 2012 R2 Base AMIのAMI ID
- インスタンスタイプ
- キーペア
- インスタンスを作成するサブネットID
- インスタンスを作成するVPC ID
- セキュリティグループのソースIP（TCP 3389、443、905が許可されます）
- vCenter Server管理者ユーザー(Administrator@vsphere.local)のパスワード
- 事前準備で作成したSnapshot ID

テンプレートを実行すると以下のリソースが作成されます。

- vCenter ServerのインストールメディアがアタッチされたWindows Server 2012 R2インスタンス
- vCenter Server用のセキュリティグループ

インスタンス作成後、リモートデスクトップでインスタンスにログインすると、vCenter Server のインストーラが自動で実行されます。
インストールが完了するまで10分～20分程度かかるので、インストーラのウインドウが消えるまでそのまま待ってください。
インストールが完了すると、デスクトップのvSphere ClientからvCenter Serverに接続できるようになります。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/51577/3bacad57-0818-2112-cea4-b2844099e158.png)


# CloudFormationテンプレート
```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "vCenter Server installed on Windows Server 2012 R2",
    "Parameters": {
        "AmiId":{
            "Type":"String",
            "Default":"ami-3f18f23f",
            "Description":"Windows Server 2012 R2 Base AMI Id.Default AMI is for Tokyo region."
        },
        "InstanceType":{
            "Type":"String",
            "Default":"m3.large",
            "Description":"Instance type"
        },
        "KeyPair":{
            "Type":"AWS::EC2::KeyPair::KeyName",
            "Description":"Key pair name"
        },
        "SubnetId":{
            "Type":"AWS::EC2::Subnet::Id",
            "Description":"Subnet Id"
        },
        "VpcId":{
            "Type":"AWS::EC2::VPC::Id",
            "Description":"Vpc Id"
        },
        "SecurityGroupSourceCidr":{
            "Type":"String",
            "Default":"0.0.0.0/0",
            "Description":"Security Group Source Cidr for TCP 3389, 443, 905"
        },
        "vCenterPassword":{
            "Type":"String",
            "Description":"Password for vCenter Admin user(Administrator@vsphere.local)",
            "NoEcho":"True"
        },
        "vCenterMediaSnapshotId":{
            "Type":"String",
            "Description":"vCenter Media SnapshotId"
        }
    },
    "Resources": {
        "vCenterSecurityGroup":{
           "Type" : "AWS::EC2::SecurityGroup",
           "Properties" : {
              "GroupDescription" : "Allow http to client host",
              "VpcId" : {"Ref" : "VpcId"},
              "SecurityGroupIngress" : [{
                    "IpProtocol" : "tcp",
                    "FromPort" : "3389",
                    "ToPort" : "3389",
                    "CidrIp" : {"Ref" : "SecurityGroupSourceCidr"}
                 },
                 {
                    "IpProtocol" : "tcp",
                    "FromPort" : "443",
                    "ToPort" : "443",
                    "CidrIp" : {"Ref" : "SecurityGroupSourceCidr"}
                 },
                 {
                    "IpProtocol" : "tcp",
                    "FromPort" : "905",
                    "ToPort" : "905",
                    "CidrIp" : {"Ref" : "SecurityGroupSourceCidr"}
                 }],
              "SecurityGroupEgress" : [{
                 "IpProtocol" : "-1",
                 "CidrIp" : "0.0.0.0/0"
              }]
           }
        },
        "vCenterInstance": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {
                "AWS::CloudFormation::Init": {
                    "config": {
                        "files": {
                            "c:\\cfn\\scripts\\installer5.5u1.bat": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "start /wait D:\\vSphere-Client\\VMware-viclient.exe /S /v\" /qr \"",
                                            "\n",
                                            "SET /P IP=< C:\\cfn\\scripts\\ip.txt",
                                            "\n",
                                            "start /wait msiexec.exe /i \"D:\\Single Sign-On\\VMware-SSO-Server.msi\" /qr SSO_HTTPS_PORT=7444 DEPLOYMODE=FIRSTDOMAIN ADMINPASSWORD=",
                                            {"Ref":"vCenterPassword"},
                                            " SSO_SITE=mysite  /l*v \"C:\\cfn\\log\\vim-sso-msi.log\" ",
                                            "\n",
                                            "start /wait D:\\\"Inventory Service\"\\VMware-inventory-service.exe /S /v\" QUERY_SERVICE_NUKE_DATABASE=0 SSO_ADMIN_USER=\\\"administrator@vsphere.local\\\" SSO_ADMIN_PASSWORD=\\\"",
                                            {"Ref":"vCenterPassword"},
                                            "\\\" LS_URL=\"https://%IP%:7444/lookupservice/sdk\" HTTPS_PORT=10443 FEDERATION_PORT=10111 XDB_PORT=10109 TOMCAT_MAX_MEMORY_OPTION=S /L*V \\\"C:\\cfn\\log\\vim-qs-msi.log\\\" /qr\" ",
                                            "\n",
                                            "start /wait D:\\vCenter-Server\\VMware-vcserver.exe /S /v\"/qr DB_SERVER_TYPE=Bundled FORMAT_DB=1 SSO_ADMIN_USER=\\\"administrator@vsphere.local\\\" SSO_ADMIN_PASSWORD=\\\"",
                                            {"Ref":"vCenterPassword"},
                                            "\\\" LS_URL=\\\"https://%IP%:7444/lookupservice/sdk\\\" IS_URL=\\\"https://%IP%:10443/\\\" VC_ADMIN_USER=administrator@vsphere.local /L*v \\\"C:\\cfn\\log\\vmvcsvr.log\\\" ",
                                            "\n",
                                            "del \"C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\setup.bat\" "
                                        ]
                                    ]
                                }
                            },
                            "C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\setup.bat": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                        "C:\\cfn\\scripts\\installer5.5u1.bat"
                                        ]
                                    ]
                                }
                            }
                        },
                        "commands": {
                            "1-setTimeZone": {
                                "command": "tzutil /s \"Tokyo Standard Time\" "
                            },
                            "2-setInstallMedia": {
                                "command": "powershell \"Get-Disk |Where-Object {$_.OperationalStatus -eq 'Offline'} | Set-Disk -IsOffline $false \" "
                            },
                            "3-getPrivateIp": {
                                "command": "powershell \"Get-WMIObject Win32_NetworkAdapterConfiguration | Where-Object {$_.DHCPEnabled -eq $true} |%{$_.IPAddress} |Out-File C:\\cfn\\scripts\\ip.txt -encoding Default\" "
                            }
                        }
                    }
                }
            },
            "Properties": {
                "ImageId": {"Ref":"AmiId"},
                "InstanceType": {"Ref":"InstanceType"},
                "NetworkInterfaces": [
                    {
                        "DeviceIndex": "0",
                        "SubnetId": {"Ref":"SubnetId"},
                        "GroupSet": [
                             {"Fn::GetAtt":["vCenterSecurityGroup","GroupId"]}
                        ],
                        "AssociatePublicIpAddress": true
                    }
                ],
                "KeyName": {"Ref":"KeyPair"},
                "BlockDeviceMappings": [
                    {
                        "DeviceName": "/dev/sda1",
                        "Ebs": {
                            "VolumeSize": "80",
                            "VolumeType": "gp2"
                        }
                    },
                    {
                        "DeviceName": "/dev/xvdf",
                        "Ebs": {
                            "SnapshotId": {"Ref":"vCenterMediaSnapshotId"},
                            "VolumeSize": "5",
                            "VolumeType": "gp2"
                        }
                    }
                ],
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "<script>\n",
                                "cfn-init.exe -v -s ",
                                {
                                    "Ref": "AWS::StackId"
                                },
                                " -r vCenterInstance",
                                " --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "\n",
                                "</script>"
                            ]
                        ]
                    }
                }
            }
        }
    },
    "Outputs": {
        "Instance": {
            "Value": {
                "Fn::GetAtt": [
                    "vCenterInstance",
                    "PublicDnsName"
                ]
            },
            "Description": "DNS Name of the newly created EC2 instance"
        },
        "Command": {
            "Value": {
                "Fn::Join": [
                    "",
                    [
                        "mstsc /v:",
                        {
                            "Fn::GetAtt": [
                                "vCenterInstance",
                                "PublicDnsName"
                            ]
                        }
                    ]
                ]
            },
            "Description": "Command to connect the instance."
        }
    }
}
```