AWS CloudFormation クライアントVPNエンドポイントの作成

# CloudFormation

これから使用するリソースをテンプレートと呼ばれるCloudFormationで用いるテキストファイルに記述することで、マネジメントコンソールやCLIを用いなくとも自動で作成してくれるサービス。例えば、VPCとサブネットを作成する場合、CIDRなどの必要事項を記述すれば、VPC → サブネットの順に依存関係まで考慮して作成してくれる。

特にクライアントVPNではACMを利用したりネットワークの関連付けをしたりするなど、あちこち行ったり来たりするのでリソースをまとめて管理するメリットは大きいと思われる。

また、削除も一括で行ってくれるのでリソースの消し忘れも防ぐことができる。

# クライアントVPNエンドポイント

インターネットから分離したVPCに安全にアクセスするためのサービス。例えば、EC2インスタンスにログインするためには通常パブリックサブネットにインスタンスを置く必要があるが、その状況ではインターネットからの不特定なアクセスを許してしまう可能性がある。クライアントVPNエンドポイントを使うことで、プライベートサブネットに配置したインスタンスにアクセスすることが可能である。


# テンプレートについての注意点

- 今回のテンプレートではACMに証明書をあらかじめ用意しておき、そのARNを指定している
- 認証方法には、相互認証・ディレクトリ認証を使用している

- テンプレートは、JSONまたはyaml形式で作成する

今回はJSONで書いたがこれをyaml形式に変換するには次の手順を踏めばよい。

変換手順
１. スタックの作成をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/39fd824f-c74b-0b92-e578-ab5c9c36d720.png)


２. デザイナーでテンプレートを作成をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/11b9c14c-0e1b-dd4e-fba4-8f599b9a34d2.png)


３. YAMLを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/0e9769c4-a17d-e5f1-994d-7c427eb69410.png)


変換できればメッセージに表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/925193a4-36d5-e86a-3363-14279f07e0e0.png)



# テンプレート

```json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
      "VPC": {
          "Type": "AWS::EC2::VPC",
          "Properties": {
              "CidrBlock": "10.0.0.0/16",
              "EnableDnsSupport": true,
              "EnableDnsHostnames": true
          }
      },
      "Subnet1": {
          "Type": "AWS::EC2::Subnet",
          "Properties": {
              "VpcId": {
                  "Ref": "VPC"
              },
              "CidrBlock": "10.0.0.0/24",
              "AvailabilityZone": "ap-northeast-1d"
          }
      },
      "Subnet2": {
          "Type": "AWS::EC2::Subnet",
          "Properties": {
              "VpcId": {
                  "Ref": "VPC"
              },
              "CidrBlock": "10.0.1.0/24",
              "AvailabilityZone": "ap-northeast-1c"
          }
      },
      "ClientVpnAuthorizationRule": {
          "Type": "AWS::EC2::ClientVpnAuthorizationRule",
          "Properties": {
              "ClientVpnEndpointId": {
                  "Ref": "ClientVpnEndpoint"
              },
              "AuthorizeAllGroups": true,
              "TargetNetworkCidr": "0.0.0.0/0"
          }
      },
      "ClientVpnEndpoint": {
          "Type": "AWS::EC2::ClientVpnEndpoint",
          "Properties": {
              "ServerCertificateArn": "arn:aws:acm:ap-northeast-1:012345678912:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "AuthenticationOptions": [
                  {
                      "MutualAuthentication": {
                          "ClientRootCertificateChainArn": "arn:aws:acm:ap-northeast-1:012345678912:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                      },
                      "Type": "certificate-authentication"
                  },
                  {
                      "ActiveDirectory": {
                          "DirectoryId": {
                              "Ref": "SimpleAD"
                          }
                      },
                      "Type": "directory-service-authentication"
                  }
              ],
              "ClientCidrBlock": "10.1.0.0/22",
              "ConnectionLogOptions": {
                  "Enabled": false
              },
              "SplitTunnel": true
          }
      },
      "ClientVpnTargetNetworkAssociation": {
          "Type": "AWS::EC2::ClientVpnTargetNetworkAssociation",
          "Properties": {
              "ClientVpnEndpointId": {
                  "Ref": "ClientVpnEndpoint"
              },
              "SubnetId": {
                  "Ref": "Subnet1"
              }
          }
      },
      "SimpleAD": {
          "Type": "AWS::DirectoryService::SimpleAD",
          "Properties": {
              "Name": "example.com",
              "Password": "Ab12345!",
              "Size": "Small",
              "VpcSettings": {
                  "SubnetIds": [
                      {
                          "Ref": "Subnet1"
                      },
                      {
                          "Ref": "Subnet2"
                      }
                  ],
                  "VpcId": {
                      "Ref": "VPC"
                  }
              }
          }
      },
      "DHCPOptions": {
          "Type": "AWS::EC2::DHCPOptions",
          "Properties": {
              "DomainName": "example.com",
              "DomainNameServers": {
                  "Fn::GetAtt": [
                      "SimpleAD",
                      "DnsIpAddresses"
                  ]
              }
          }
      }
  }
}
```

# 参考記事

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/what-is.html

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-splittunnel

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-targetnetworkcidr

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html#cfn-ec2-clientvpntargetnetworkassociation-clientvpnendpointid

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-directoryservice-simplead-vpcsettings.html

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-domainnameservers

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html