From 736877330b00486a8f75b3367bae7c3df7732128 Mon Sep 17 00:00:00 2001
From: "S. X. Liang" <60531983+Scottpedia@users.noreply.github.com>
Date: Wed, 26 Aug 2020 23:20:04 -0400
Subject: [PATCH] Add AWS deployment template (#838)
Add AWS deployment template
Authored-by: Scottpedia (https://github.com/Scottpedia)
---
README-zh.md | 2 +-
README.md | 2 +-
aws/README.md | 61 ++
aws/cloudformation-template-ipsec | 806 ++++++++++++++++++
aws/confirm-iam.png | Bin 0 -> 342089 bytes
aws/show-key.png | Bin 0 -> 678877 bytes
aws/specify-parameters.png | Bin 0 -> 286098 bytes
aws/upload-the-template.png | Bin 0 -> 381283 bytes
.../cloudformation-launch-stack-button.png | Bin 0 -> 2296 bytes
9 files changed, 869 insertions(+), 2 deletions(-)
create mode 100644 aws/README.md
create mode 100644 aws/cloudformation-template-ipsec
create mode 100644 aws/confirm-iam.png
create mode 100644 aws/show-key.png
create mode 100644 aws/specify-parameters.png
create mode 100644 aws/upload-the-template.png
create mode 100644 docs/images/cloudformation-launch-stack-button.png
diff --git a/README-zh.md b/README-zh.md
index 094478b..0c3fe22 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -65,7 +65,7 @@ wget https://git.io/vpnsetup -O vpnsetup.sh && sudo sh vpnsetup.sh
- CentOS 6 (x86_64) with Updates
- Red Hat Enterprise Linux (RHEL) 8, 7 或者 6
-请参见 详细步骤 以及 EC2 定价细节。
+请参见 详细步骤 以及 EC2 定价细节。另外,你也可以参见[此页面](aws/README.md)来了解如何使用**AWS Cloudformation**来快速在EC2上部署一个VPN服务器。
**-或者-**
diff --git a/README.md b/README.md
index cf0236d..35463fb 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,7 @@ A newly created Amazon EC2
- CentOS 6 (x86_64) with Updates
- Red Hat Enterprise Linux (RHEL) 8, 7 or 6
-Please see detailed instructions and EC2 pricing.
+Please see detailed instructions and EC2 pricing. As an alternative, you can also launch a VPN server on EC2 with **AWS Cloudformation**. See detailed instructions [here](aws/README.md).
**-OR-**
diff --git a/aws/README.md b/aws/README.md
new file mode 100644
index 0000000..62ffeb5
--- /dev/null
+++ b/aws/README.md
@@ -0,0 +1,61 @@
+# Deploy to AWS (Beta)
+
+> **Note:** The AWS deployment template is still in **BETA** phase. You may encounter failures during the deployment. In that case, please let us know the issue.
+
+This template will create a fully-working IPSec/L2TP VPN server on AWS (Amazon Web Service). Please make sure to check the [pricing details](https://aws.amazon.com/ec2/pricing/on-demand/) of Virtual Machine on EC2 before starting the launch sequence.
+
+You can also use `t2.micro` instance as your server for your deployment, which is free of charge within the first year since your AWS account is registered. For more information on AWS free usage tier, go to [this page](https://aws.amazon.com/free/).
+
+## Available Customization Parameters:
+
+- AWS EC2 Instance Type
+- OS for your VPN Server (Ubuntu16.04, Ubuntu18.04, Debian9-Stretch or Debian10-Buster)
+> **Note:** To use Debian9 or Debian10 images on EC2, to need to subscribe them first at AWS marketplace. [**Debian9**](https://aws.amazon.com/marketplace/pp/B073HW9SP3) [**Debian10**](https://aws.amazon.com/marketplace/pp/B0859NK4HC)
+- Your VPN username
+- Your VPN password
+- IPSec PSK (pre-shared key)
+
+> When choosing your username and password, do not enter special characters like `" ' \`.
+
+Make sure to do this with an **AWS ROOT ACCOUNT** or an **IAM ACCOUNT** with **ANDMINISTRATOR ACCESS**.
+
+Right-click the [**template link**](https://raw.githubusercontent.com/hwdsl2/setup-ipsec-vpn/master/aws/cloudformation-template-ipsec) and save it as a file on your computer. Then upload it as the template source in the stack creation wizard.
+
+![Upload the file](upload-the-template.png)
+
+At step 4, make sure to confirm that this template may create IAM resources.
+
+![Confirm IAM](confirm-iam.png)
+
+Click the icon below to initiate the launching sequence.
+
+
+
+Make sure the deployment is successful before going to [Next Step: Configure VPN Clients](https://git.io/vpnclients).
+
+> **Note:** You need to wait for around 5 minutes after the stack is shown as **"CREATE_COMPLETE"**, before you can connect to the server with a VPN client. That's for the installation script to finish.
+
+# FAQs
+
+
+How to connect to the server via ssh after deployment?
+
+
+AWS does not allow users to access the instances with an SSH password. Instead, users are instructed to create "key pairs", which are used as credentials to access the instances via SSH.
+
+The template here generates a key pair for you during the deployment, and that will be available as plain texts in the **"Output"** section after the stack is successfully created.
+
+You need to note down that key file if you want to later access the VPN server via SSH.
+
+![](show-key.png)
+
+
diff --git a/aws/cloudformation-template-ipsec b/aws/cloudformation-template-ipsec
new file mode 100644
index 0000000..32dea39
--- /dev/null
+++ b/aws/cloudformation-template-ipsec
@@ -0,0 +1,806 @@
+{
+ "AWSTemplateFormatVersion": "2010-09-09",
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "0a162613-8f2e-4864-be99-75d946934a4a": {
+ "size": {
+ "width": 350,
+ "height": 440
+ },
+ "position": {
+ "x": 290,
+ "y": 70
+ },
+ "z": 1,
+ "embeds": [
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2"
+ ]
+ },
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2": {
+ "size": {
+ "width": 290,
+ "height": 360
+ },
+ "position": {
+ "x": 310,
+ "y": 110
+ },
+ "z": 2,
+ "parent": "0a162613-8f2e-4864-be99-75d946934a4a",
+ "embeds": [
+ "9d4cbbc2-f521-436d-bb4a-85b82cf22a2a",
+ "464ea4ae-199c-4917-9404-aed674a8615a",
+ "ec256f27-66c3-423c-9d98-b9f0f634e7b8",
+ "4731d93c-f3fc-420a-b535-f0b99840f356",
+ "40c2d4e7-f01a-45b2-8878-a06680aa2216"
+ ],
+ "dependson": [
+ "0a162613-8f2e-4864-be99-75d946934a4a",
+ "464ea4ae-199c-4917-9404-aed674a8615a"
+ ]
+ },
+ "4731d93c-f3fc-420a-b535-f0b99840f356": {
+ "size": {
+ "width": 230,
+ "height": 130
+ },
+ "position": {
+ "x": 350,
+ "y": 320
+ },
+ "z": 3,
+ "parent": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "embeds": [
+ "5262ea47-2337-4be8-a4d1-1f0af38a1731"
+ ],
+ "iscontainedinside": [
+ "0a162613-8f2e-4864-be99-75d946934a4a"
+ ],
+ "dependson": [
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2"
+ ]
+ },
+ "5262ea47-2337-4be8-a4d1-1f0af38a1731": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 440,
+ "y": 350
+ },
+ "z": 4,
+ "parent": "4731d93c-f3fc-420a-b535-f0b99840f356",
+ "embeds": [],
+ "isassociatedwith": [
+ "db7c3441-9f9a-4677-a14d-bccfc06714d1"
+ ],
+ "dependson": [
+ "4731d93c-f3fc-420a-b535-f0b99840f356",
+ "9d3d19ab-d561-4f59-89de-73498eeeebda",
+ "464ea4ae-199c-4917-9404-aed674a8615a"
+ ]
+ },
+ "464ea4ae-199c-4917-9404-aed674a8615a": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 510,
+ "y": 220
+ },
+ "z": 3,
+ "parent": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "embeds": [],
+ "dependson": [
+ "0a162613-8f2e-4864-be99-75d946934a4a"
+ ]
+ },
+ "40c2d4e7-f01a-45b2-8878-a06680aa2216": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 430,
+ "y": 140
+ },
+ "z": 3,
+ "parent": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "embeds": [],
+ "iscontainedinside": [
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2"
+ ],
+ "dependson": [
+ "4731d93c-f3fc-420a-b535-f0b99840f356",
+ "9d4cbbc2-f521-436d-bb4a-85b82cf22a2a",
+ "99fce86e-18b8-4b1b-a572-7bef3c5cece7",
+ "58a1ab6f-49ac-4ffa-93c7-3f708bf65871",
+ "ec256f27-66c3-423c-9d98-b9f0f634e7b8"
+ ]
+ },
+ "9d4cbbc2-f521-436d-bb4a-85b82cf22a2a": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 350,
+ "y": 140
+ },
+ "z": 3,
+ "parent": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "embeds": []
+ },
+ "ec256f27-66c3-423c-9d98-b9f0f634e7b8": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 430,
+ "y": 220
+ },
+ "z": 3,
+ "parent": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2",
+ "embeds": [],
+ "iscontainedinside": [
+ "0a162613-8f2e-4864-be99-75d946934a4a"
+ ]
+ },
+ "5bb16646-dc1e-4661-9164-6ecc6848dc83": {
+ "source": {
+ "id": "4731d93c-f3fc-420a-b535-f0b99840f356"
+ },
+ "target": {
+ "id": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2"
+ },
+ "z": 3
+ },
+ "99fce86e-18b8-4b1b-a572-7bef3c5cece7": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 150,
+ "y": 250
+ },
+ "z": 1,
+ "embeds": []
+ },
+ "58a1ab6f-49ac-4ffa-93c7-3f708bf65871": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 150,
+ "y": 170
+ },
+ "z": 1,
+ "embeds": []
+ },
+ "d3fab7a7-d694-435e-930d-ff7693dffbbc": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 110,
+ "y": 90
+ },
+ "z": 1,
+ "embeds": []
+ },
+ "2c5cc5a9-5a17-4d54-80ea-56e204c9c1a1": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 70,
+ "y": 170
+ },
+ "z": 1,
+ "embeds": []
+ },
+ "e81dfbbc-e8ee-4f4b-adb0-b314056ab0b3": {
+ "size": {
+ "width": 60,
+ "height": 60
+ },
+ "position": {
+ "x": 70,
+ "y": 250
+ },
+ "z": 1,
+ "embeds": []
+ },
+ "9d3d19ab-d561-4f59-89de-73498eeeebda": {
+ "source": {
+ "id": "0a162613-8f2e-4864-be99-75d946934a4a"
+ },
+ "target": {
+ "id": "464ea4ae-199c-4917-9404-aed674a8615a"
+ },
+ "z": 3
+ },
+ "361e0035-6c5a-48df-8339-3e31f19bf032": {
+ "source": {
+ "id": "9d4cbbc2-f521-436d-bb4a-85b82cf22a2a"
+ },
+ "target": {
+ "id": "40c2d4e7-f01a-45b2-8878-a06680aa2216"
+ },
+ "z": 3
+ }
+ }
+ },
+ "Resources": {
+ "VpnVpc": {
+ "Type": "AWS::EC2::VPC",
+ "Properties": {
+ "CidrBlock": "10.0.0.0/24"
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "0a162613-8f2e-4864-be99-75d946934a4a"
+ }
+ }
+ },
+ "VpnSubnet": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "VpnVpc"
+ },
+ "CidrBlock": "10.0.0.0/24",
+ "MapPublicIpOnLaunch": true,
+ "AvailabilityZone": {
+ "Fn::Sub": "${AWS::Region}a"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "5198eb6d-da4f-43e2-8a4b-b9bff02b26a2"
+ }
+ },
+ "DependsOn": [
+ "VpnVpc",
+ "VpcInternetGateway"
+ ]
+ },
+ "VpnRouteTable": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "VpnVpc"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "4731d93c-f3fc-420a-b535-f0b99840f356"
+ }
+ },
+ "DependsOn": [
+ "VpnSubnet"
+ ]
+ },
+ "PublicInternetRoute": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "RouteTableId": {
+ "Ref": "VpnRouteTable"
+ },
+ "GatewayId": {
+ "Ref": "VpcInternetGateway"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "5262ea47-2337-4be8-a4d1-1f0af38a1731"
+ }
+ },
+ "DependsOn": [
+ "VpnRouteTable",
+ "VpcInternetGateway",
+ "InternetGatewayAttachment"
+ ]
+ },
+ "VpnInstance": {
+ "Type": "AWS::EC2::Instance",
+ "Properties": {
+ "UserData": {
+ "Fn::Base64": {
+ "Fn::Join": [
+ "",
+ [
+ "#!/bin/bash -x\n",
+ "export VPN_IPSEC_PSK='",
+ {
+ "Ref": "VpnIpsecPsk"
+ },
+ "'\n",
+ "export VPN_USER='",
+ {
+ "Ref": "VpnUser"
+ },
+ "'\n",
+ "export VPN_PASSWORD='",
+ {
+ "Ref": "VpnPassword"
+ },
+ "'\n",
+ "sleep 60\n",
+ "wget https://git.io/vpnsetup -O vpnsetup.sh && sh vpnsetup.sh\n"
+ ]
+ ]
+ }
+ },
+ "SecurityGroupIds": [
+ {
+ "Fn::GetAtt": [
+ "VpnSecurityGroup",
+ "GroupId"
+ ]
+ }
+ ],
+ "SubnetId": {
+ "Ref": "VpnSubnet"
+ },
+ "AvailabilityZone": {
+ "Fn::Sub": "${AWS::Region}a"
+ },
+ "InstanceType": {
+ "Ref": "InstanceType"
+ },
+ "KeyName": {
+ "Fn::GetAtt": [
+ "KeyPairInfo",
+ "KeyName"
+ ]
+ },
+ "ImageId": {
+ "Fn::GetAtt": [
+ "AMIInfo",
+ "AMIId"
+ ]
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "40c2d4e7-f01a-45b2-8878-a06680aa2216"
+ }
+ },
+ "DependsOn": [
+ "VpnRouteTable",
+ "VpnServerVolume",
+ "KeyPairCreation",
+ "AMIInfoFunction",
+ "VpnSecurityGroup"
+ ]
+ },
+ "VpnSecurityGroup": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "The VPN Security Group, allowing ingress UDP traffic at port 4500 and 500.",
+ "GroupName": "VpnSecurityGroup",
+ "VpcId": {
+ "Ref": "VpnVpc"
+ },
+ "SecurityGroupIngress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "IpProtocol": "tcp",
+ "FromPort": 22,
+ "ToPort": 22
+ },
+ {
+ "CidrIp": "0.0.0.0/0",
+ "IpProtocol": "udp",
+ "FromPort": 500,
+ "ToPort": 500
+ },
+ {
+ "CidrIp": "0.0.0.0/0",
+ "IpProtocol": "udp",
+ "FromPort": 4500,
+ "ToPort": 4500
+ }
+ ],
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "IpProtocol": -1
+ }
+ ]
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "ec256f27-66c3-423c-9d98-b9f0f634e7b8"
+ }
+ }
+ },
+ "VpnServerVolume": {
+ "Type": "AWS::EC2::Volume",
+ "Properties": {
+ "AvailabilityZone": {
+ "Fn::Sub": "${AWS::Region}a"
+ },
+ "Size": 8
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "9d4cbbc2-f521-436d-bb4a-85b82cf22a2a"
+ }
+ }
+ },
+ "VpcInternetGateway": {
+ "Type": "AWS::EC2::InternetGateway",
+ "Properties": {},
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "464ea4ae-199c-4917-9404-aed674a8615a"
+ }
+ },
+ "DependsOn": [
+ "VpnVpc"
+ ]
+ },
+ "EC2SRTA4VJU5": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpnRouteTable"
+ },
+ "SubnetId": {
+ "Ref": "VpnSubnet"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "5bb16646-dc1e-4661-9164-6ecc6848dc83"
+ }
+ }
+ },
+ "KeyPairCreation": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Handler": "index.handler",
+ "Runtime": "python3.7",
+ "Role": {
+ "Fn::GetAtt": [
+ "LambdaExecutionRole",
+ "Arn"
+ ]
+ },
+ "Timeout": 30,
+ "Code": {
+ "ZipFile": {
+ "Fn::Join": [
+ "\n",
+ [
+ "import boto3",
+ "import cfnresponse",
+ "import string",
+ "import random",
+ "'''",
+ "This python program should be embedded into its designated cloudformation",
+ "template as the inline code of one of the lambda functions.",
+ "'''",
+ "def handler(event, context):",
+ " try:",
+ " keyName = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(10))",
+ " region = event['ResourceProperties']['Region']",
+ " ec2 = boto3.client('ec2',region)",
+ " response = ec2.create_key_pair(",
+ " KeyName=keyName",
+ " )",
+ " keyMaterial = response['KeyMaterial']",
+ " cfnresponse.send(event, context, cfnresponse.SUCCESS, {'KeyMaterial':keyMaterial, 'KeyName':keyName}, 'KeyPairInfo')",
+ " except Exception:",
+ " cfnresponse.send(event, context, cfnresponse.FAILED, {})"
+ ]
+ ]
+ }
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "99fce86e-18b8-4b1b-a572-7bef3c5cece7"
+ }
+ },
+ "DependsOn": [
+ "LambdaExecutionRole"
+ ]
+ },
+ "AMIInfo": {
+ "Type": "Custom::AMIInfo",
+ "Properties": {
+ "Region": {
+ "Ref": "AWS::Region"
+ },
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AMIInfoFunction",
+ "Arn"
+ ]
+ },
+ "Distribution": {
+ "Ref": "OS"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "2c5cc5a9-5a17-4d54-80ea-56e204c9c1a1"
+ }
+ },
+ "DependsOn": [
+ "AMIInfoFunction"
+ ]
+ },
+ "AMIInfoFunction": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Handler": "index.handler",
+ "Runtime": "python3.7",
+ "Role": {
+ "Fn::GetAtt": [
+ "LambdaExecutionRole",
+ "Arn"
+ ]
+ },
+ "Code": {
+ "ZipFile": {
+ "Fn::Join": [
+ "\n",
+ [
+ "import boto3",
+ "import cfnresponse",
+ "def creation_date(e):",
+ " return e['CreationDate']",
+ "",
+ "def handler(event, context):",
+ " try:",
+ " regionName = event['ResourceProperties']['Region']",
+ " distribution = event['ResourceProperties']['Distribution']",
+ " ec2 = boto3.client('ec2',regionName)",
+ " IAMName = ''",
+ " if distribution == 'Ubuntu16.04':",
+ " IAMName = 'ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*'",
+ " elif distribution == 'Ubuntu18.04':",
+ " IAMName = 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*'",
+ " elif distribution == 'Ubuntu20.04':",
+ " IAMName = 'ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*'",
+ " elif distribution == 'Debian9':",
+ " IAMName = 'debian-stretch-hvm-x86_64-gp2-*'",
+ " elif distribution == 'Debian10':",
+ " IAMName = 'debian-10-amd64-*'",
+ " response = ec2.describe_images(Filters=[{'Name':'name', 'Values':[IAMName]}])",
+ " images = response['Images']",
+ " images.sort(key=creation_date,reverse=True)",
+ " AMIId = images[0]['ImageId']",
+ " cfnresponse.send(event, context, cfnresponse.SUCCESS, {'AMIId':AMIId}, 'AMIInfo')",
+ " except Exception:",
+ " cfnresponse.send(event, context, cfnresponse.FAILED, {})"
+ ]
+ ]
+ }
+ },
+ "Timeout": 30
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "58a1ab6f-49ac-4ffa-93c7-3f708bf65871"
+ }
+ },
+ "DependsOn": [
+ "LambdaExecutionRole"
+ ]
+ },
+ "LambdaExecutionRole": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ },
+ "Action": [
+ "sts:AssumeRole"
+ ]
+ },
+ {
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "ec2.amazonaws.com"
+ ]
+ },
+ "Action": [
+ "sts:AssumeRole"
+ ]
+ }
+ ]
+ },
+ "Path": "/",
+ "Policies": [
+ {
+ "PolicyName": "root",
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": "*",
+ "Resource": "*"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "d3fab7a7-d694-435e-930d-ff7693dffbbc"
+ }
+ }
+ },
+ "KeyPairInfo": {
+ "Type": "Custom::KeyPairInfo",
+ "Properties": {
+ "Region": {
+ "Ref": "AWS::Region"
+ },
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "KeyPairCreation",
+ "Arn"
+ ]
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "e81dfbbc-e8ee-4f4b-adb0-b314056ab0b3"
+ }
+ },
+ "DependsOn": [
+ "KeyPairCreation"
+ ]
+ },
+ "InternetGatewayAttachment": {
+ "Type": "AWS::EC2::VPCGatewayAttachment",
+ "Properties": {
+ "InternetGatewayId": {
+ "Ref": "VpcInternetGateway"
+ },
+ "VpcId": {
+ "Ref": "VpnVpc"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "9d3d19ab-d561-4f59-89de-73498eeeebda"
+ }
+ }
+ },
+ "EC2VA41EUF": {
+ "Type": "AWS::EC2::VolumeAttachment",
+ "Properties": {
+ "Device": "/dev/sdh",
+ "VolumeId": {
+ "Ref": "VpnServerVolume"
+ },
+ "InstanceId": {
+ "Ref": "VpnInstance"
+ }
+ },
+ "Metadata": {
+ "AWS::CloudFormation::Designer": {
+ "id": "361e0035-6c5a-48df-8339-3e31f19bf032"
+ }
+ }
+ }
+ },
+ "Parameters": {
+ "VpnUser": {
+ "Type": "String",
+ "Description": "Your VPN username"
+ },
+ "VpnIpsecPsk": {
+ "Type": "String",
+ "Description": "Your IpSec PSK(Pre-shared Key) for the VPN server."
+ },
+ "VpnPassword": {
+ "Type": "String",
+ "Description": "Your VPN password."
+ },
+ "OS": {
+ "Type": "String",
+ "Description": "The OS of your VPN server. Choose the default value if you don't know what it is.",
+ "Default": "Ubuntu16.04",
+ "AllowedValues": [
+ "Ubuntu16.04",
+ "Ubuntu18.04",
+ "Ubuntu20.04",
+ "Debian9",
+ "Debian10"
+ ]
+ },
+ "InstanceType": {
+ "Type": "String",
+ "Description": "The instance type of VPN server. If you want to build your server within AWS free usage tier, select t2.micro.",
+ "AllowedValues": [
+ "t2.micro",
+ "t3.nano",
+ "m5.large",
+ "t3.micro",
+ "t3.small",
+ "t2.nano",
+ "t2.small",
+ "t3a.nano",
+ "t3a.micro",
+ "t3a.small",
+ "m5a.large",
+ "t1.micro"
+ ],
+ "Default": "t2.micro"
+ }
+ },
+ "Outputs": {
+ "VPNAddress": {
+ "Description": "This is the Public IP of your newly-launched VPN server",
+ "Value": {
+ "Fn::GetAtt": [
+ "VpnInstance",
+ "PublicIp"
+ ]
+ }
+ },
+ "VPNUsername": {
+ "Description": "Your VPN username",
+ "Value": {
+ "Ref": "VpnUser"
+ }
+ },
+ "VPNPassword": {
+ "Description": "Your VPN password",
+ "Value": {
+ "Ref": "VpnPassword"
+ }
+ },
+ "VPNKey": {
+ "Description": "Your IPSec VPN PSK(pre-shared key)",
+ "Value": {
+ "Ref": "VpnIpsecPsk"
+ }
+ },
+ "EC2PrivateKeyMaterial": {
+ "Description": "The content of your private key for accessing the VPN server via SSH. Save it as a file and use it when you connect to your server via SSH.",
+ "Value": {
+ "Fn::GetAtt": [
+ "KeyPairInfo",
+ "KeyMaterial"
+ ]
+ }
+ },
+ "NextStep": {
+ "Description": "Go to this page for how to configure to VPN clients.",
+ "Value": "https://git.io/vpnclients"
+ }
+ }
+}
diff --git a/aws/confirm-iam.png b/aws/confirm-iam.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b5ed1172197278cfd82a13b2f58674b589b561
GIT binary patch
literal 342089
zcmeFZbyS
b b
zdfH+nSy7I0X^SJmlzp$I7JrC{WXv7r_a*NzAL~Afq~P!yRtF`9$9>FSt3oy8pM6Vb
z2K=R6wA7`~+KoPYdEl!ns+f7!7T6Cjg$EuLH{ZsQV`RU?5bHr85PYW>kT32Z_xLad
z)W+Qv)#=(AS~rZI>GMAs#9DlMCVE=%yxHEb7fbob9>Ffj63qMnF?)#)JL1i?WGxgG
zF e90miMN1Ve*5pm9T$-F&Nzeap^gkh^33
z^?t{My+LCBfPz3$7E&=dnb%zQkU#hL%3<_jS5TAlIa;PxTn9-6295tioOlTVW4PJ$
z-DlzFZg)PH`32L(dlZrR4#=qntK!Y$U#AK32u=3CtD}HA`u ?51>}MBH?B6xn~kUmwplv4z{!EeG3Yq2-y2+r=dn$*K|v
zvRA?bFsTM3q|8u&Ua>`0qn}e3BGcmhvT5#G!pP%&6gj_wAH^N}EdckTj_&S(!hCim
zUIxnoF~Jz$Y)!hOXTJTk;`=+rk04^C@140x{#731R}Knub7>I+Plbqi(4I>IlX5_}
zcf*qVAt(GPG<(qKM*Ll2PnevB0xZ%Jpn^G;Z4F5dtk$@mtadJA{~CxJ%TvYEM>{r|BPe|hNjsG6GG@f#sVh{
z3s=SDyTTjT9lp8+(5Np$gLwGPb74NOp_l6W(RL{%S%U)o4B(x^Sr)tz$aeE|r&UDr
zF-`Yz%qmmY(B&~Fl%Y#GBAp6Y5gvVfLIo5AJKcl<02Q)MXeXuTn0uC)oIQQ_GXJOY)Sn<~Zw^{&sBNFfxI!Lt8)
z^-G>_j~VPeSr2U=JAzIxq@?Yc7B!Jpwk6x%@*j#FaMq`(o^p=vNb8N2P%|evt*L0P
zJKBeNRoTaN8Si+RP)E0hUh^8de$NFThR-OUC=ML*jzCU`#qyC1+5^hBXEfi@J39^8
zam<9Nz!3{E@JOFnv}`JiDvj~mfFsfuuufF&4&|AE%3|J??_tmCe~YldbRv1G7(0^Q
z+4GgM?FR`Wvs7HLc3%9;E0156dX#}P0n?6`uYSz|9}8OEYC#*~tanSO1&Y#ic-|PC
zjd>iKD|-$^u3L%wxIW!hhUS9FS+|?P@1fO)pZn0~HL&bXUnq;PDGCR!{hN$#9MeYv
zJZ}=u^QKo%E|a>3M8F%z&c$8IM+^gipFGIJg)Moe39gT~kJ)x4gm#7`*=MHMc?jxq
zN9
E^%AI_>#sc`#_n;(*<@(jHQ^Yq46in oXa!w&6)Y%oZMvIT)gvUKl|Bv_F8MN?07Ch
zGo8=BKVMX7eoBFU{;mYlh6~Yoiu5+c(6<#fdBy+>yJR0Xan-dKgEmNS(vdyO)PA0#
z2nf1)WT#`%xxEIN2trZ
xE~|Gi~*Mv4`_j#c3Gn9lnH(XZtJmVB3!BKXy+|{q~f;b
z*fmTWEqj&&aa~*)WhYyPM;scr;Ew(#+Q9E2^k!!e1t2%6U$R+Jn4M5dhK2_$eG%D|IF5rGHyTYJ;l)sW-#i{0ob)7$W#sN_AY|Rw|
z1)JOsh5iE%ZqM&djfqk)xZ8`Cpz^
zmo0iZ+&~lNm5#j71b-(}^**cI_AAM3h-33Ss>y!n@zcu=m)qLf{G(#79Z$eR8-`=SZz7++!nLF&%6>aQ9~D9
zIhQAiuV}tJ$UNgB#DwqaZ{3p0oo$}muIP78rIwY$_bV$wXU_!5hOaqih=MhW19Kmg
z%l6?a%=}KkRGwO=-Qs>skTsAI|DHV*@BfOv8-UK!Eqj*niCrjL4Dhew4maqJ^+QXT
zL+e#J$XQ)izw%7J>7w2{=hDuzHz}*!r@uLPa{-q{Je*{Z{mND=UKlI+gIS9xTS6>T
zEXIU|P4^y)qMEuv@fVb)$L87X(Cm;Q?!1CeIY42pejamt==*D7#^I#0B~Q@uk90|L
z-0Bo|yps^gZ|B7$6XiBI`t4siN0(QM+=jy(?z`WopMkFB!J6sj#&I9p?=5Rf(d{7w
z2ra=3KKJ(8ue!Qy9xR2ccPJ(?@d|YcFLAmZa$EJ$p*R8)fAq?KgTDKDlPTIIsJ1^D
zVG@tx4{J&y8%#ZUEFZ+Hsn}_sOHCR-8JN?y+wI3!n-8dv3tELMy?t-YHd|CQ7CII<
zmWelN@l~)d3%_TE8=#wu-R8B(rO#^}kXWLwz-OkO>KZauz06~Sh>3m-sJ>C4WS%0q
zh!AWr;XFl-LvnOc(ov8QFFobHlpDt@#?2}K59L`aoU=jdRxP`izDyrX^Eu8548^{0
zOAOX9+NJu!jrb6{0~dO`>)k2v7Bt>;8hIY&xGj83wet&};PrFj=n*q~6UZu45N*P=
z?`$1kyp1_%Z@hN2OzZN_)1G(lBQx#?k^%=QV=}Ar6s0#9lVok{yvvEXm&>j~cDKJC
zEIfJ7q@ghBRPxAMUh;QYrE#)7uC`}gdp%w)UOb#2lLBUTiC0-1=Im>FXGLl$qAqo{
zw)1M?B%Gy$_q+FPv=Tm|YEYt4PBdrh1gZ