Created
March 28, 2017 12:08
-
-
Save koblas/cf63055faae509fa3ec5eeca5d695b3d to your computer and use it in GitHub Desktop.
OpenVPN Cloudformation template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"Description": "EC2 OpenVPN host for stage-railz", | |
"Mappings": { | |
"AmiMap": { | |
"us-east-1": { | |
"bastion": "ami-2757f631", | |
"ecs": "ami-b2df2ca4", | |
"ubuntu1604": "ami-2757f631" | |
}, | |
"us-west-2": { | |
"bastion": "ami-7ac6491a", | |
"ecs": "ami-022b9262", | |
"ubuntu1604": "ami-7ac6491a" | |
} | |
} | |
}, | |
"Parameters": { | |
"AvailabilityZones": { | |
"Description": "Availability Zones to deploy instances in.", | |
"Type": "CommaDelimitedList" | |
}, | |
"DefaultSG": { | |
"Description": "Top level security group.", | |
"Type": "AWS::EC2::SecurityGroup::Id" | |
}, | |
"ImageName": { | |
"Default": "bastion", | |
"Description": "The image name to use from the AMIMap (usually found in the config file.)", | |
"Type": "String" | |
}, | |
"InstanceType": { | |
"Default": "m3.medium", | |
"Description": "EC2 Instance Type", | |
"Type": "String" | |
}, | |
"MaxSize": { | |
"Default": "1", | |
"Description": "Maximum # of instances.", | |
"Type": "Number" | |
}, | |
"MinSize": { | |
"Default": "1", | |
"Description": "Minimum # of instances.", | |
"Type": "Number" | |
}, | |
"OfficeNetwork": { | |
"Default": "0.0.0.0/0", | |
"Description": "CIDR block allowed to connect to bastion hosts.", | |
"Type": "String" | |
}, | |
"PrivateSubnets": { | |
"Description": "Subnets to deploy private instances in.", | |
"Type": "List<AWS::EC2::Subnet::Id>" | |
}, | |
"PublicSubnets": { | |
"Description": "Subnets to deploy public instances in.", | |
"Type": "List<AWS::EC2::Subnet::Id>" | |
}, | |
"S3VpnKeysBucketName": { | |
"Description": "The S3 bucket that contains the keys for the OpenVPN server", | |
"Type": "String" | |
}, | |
"SshKeyName": { | |
"Type": "AWS::EC2::KeyPair::KeyName" | |
}, | |
"VpcCidr": { | |
"Description": "The name of this VPC for tagging", | |
"Type": "String" | |
}, | |
"VpcId": { | |
"Description": "Vpc Id", | |
"Type": "AWS::EC2::VPC::Id" | |
}, | |
"VpcName": { | |
"Description": "The name of this VPC for tagging", | |
"Type": "String" | |
} | |
}, | |
"Resources": { | |
"AllowSSHAnywhere": { | |
"Properties": { | |
"FromPort": 22, | |
"GroupId": { | |
"Ref": "DefaultSG" | |
}, | |
"IpProtocol": "tcp", | |
"SourceSecurityGroupId": { | |
"Ref": "BastionSG" | |
}, | |
"ToPort": 22 | |
}, | |
"Type": "AWS::EC2::SecurityGroupIngress" | |
}, | |
"BastionAccessPolicy": { | |
"Properties": { | |
"PolicyDocument": { | |
"Statement": [ | |
{ | |
"Action": [ | |
"ec2:AssociateAddress", | |
"ec2:Describe", | |
"ec2:ModifyInstanceAttribute" | |
], | |
"Effect": "Allow", | |
"Resource": "*" | |
}, | |
{ | |
"Action": [ | |
"s3:Get*" | |
], | |
"Effect": "Allow", | |
"Resource": [ | |
{ | |
"Fn::Join": [ | |
"", | |
[ | |
"arn:aws:s3:::", | |
{ | |
"Ref": "S3VpnKeysBucketName" | |
} | |
] | |
] | |
}, | |
{ | |
"Fn::Join": [ | |
"", | |
[ | |
"arn:aws:s3:::", | |
{ | |
"Ref": "S3VpnKeysBucketName" | |
}, | |
"/*" | |
] | |
] | |
} | |
] | |
} | |
] | |
}, | |
"PolicyName": "BastionAccessPolicy", | |
"Roles": [ | |
{ | |
"Ref": "BastionRole" | |
} | |
] | |
}, | |
"Type": "AWS::IAM::Policy" | |
}, | |
"BastionAutoscalingGroup": { | |
"Properties": { | |
"AvailabilityZones": { | |
"Ref": "AvailabilityZones" | |
}, | |
"LaunchConfigurationName": { | |
"Ref": "BastionLaunchConfig" | |
}, | |
"MaxSize": { | |
"Ref": "MaxSize" | |
}, | |
"MinSize": { | |
"Ref": "MinSize" | |
}, | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"PropagateAtLaunch": true, | |
"Value": "stage-railz.openvpn" | |
}, | |
{ | |
"Key": "Application", | |
"PropagateAtLaunch": true, | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "network", | |
"PropagateAtLaunch": true, | |
"Value": "public" | |
} | |
], | |
"VPCZoneIdentifier": { | |
"Ref": "PublicSubnets" | |
} | |
}, | |
"Type": "AWS::AutoScaling::AutoScalingGroup" | |
}, | |
"BastionInstanceProfile": { | |
"Properties": { | |
"Path": "/", | |
"Roles": [ | |
{ | |
"Ref": "BastionRole" | |
} | |
] | |
}, | |
"Type": "AWS::IAM::InstanceProfile" | |
}, | |
"BastionLaunchConfig": { | |
"Properties": { | |
"AssociatePublicIpAddress": "true", | |
"IamInstanceProfile": { | |
"Ref": "BastionInstanceProfile" | |
}, | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AmiMap", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
{ | |
"Ref": "ImageName" | |
} | |
] | |
}, | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SshKeyName" | |
}, | |
"SecurityGroups": [ | |
{ | |
"Ref": "DefaultSG" | |
}, | |
{ | |
"Ref": "BastionSG" | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash -x\nfunction base {\n echo \"=== Boostrap Starting \"\n apt-get update\n apt-get install -y curl python-pip\n DEBIAN_FRONTEND=noninteractive apt-get install -y iptables-persistent\n pip install awscli\n\n # IP Configuration\n aws ec2 modify-instance-attribute --no-source-dest-check --instance-id `curl http://169.254.169.254/latest/meta-data/instance-id` --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"\n\n cat <<EOT > /etc/iptables/rules.v4\n*nat\n:PREROUTING ACCEPT [85:4110]\n:INPUT ACCEPT [84:4046]\n:OUTPUT ACCEPT [70:11051]\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -s 172.20.0.0/16 -o eth0 -j MASQUERADE\n-A POSTROUTING -s 172.29.0.0/20 -o eth0 -j MASQUERADE\nCOMMIT\n# Completed on Tue Mar 28 11:19:00 2017\n# Generated by iptables-save v1.6.0 on Tue Mar 28 11:19:00 2017\n*filter\n:INPUT ACCEPT [2584:919039]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [2388:528346]\n-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT\n-A FORWARD -s 172.20.0.0/16 -i eth0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\n-A FORWARD -s 172.29.0.0/20 -i tun0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\n-A FORWARD -s 172.29.0.0/20 -d 172.20.0.0/16 -i tun0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\nCOMMIT\nEOT\n\n iptables-restore < /etc/iptables/rules.v4\n\n echo \"net.ipv4.ip_forward = 1\" >> /etc/sysctl.conf\n sysctl -p\n\n # OpenVPN configuration\n\n mkdir -p /etc/openvpn/keys\n aws s3 cp s3://", | |
{ | |
"Ref": "S3VpnKeysBucketName" | |
}, | |
" /etc/openvpn/keys --recursive --include \"ca.crt\" --include \"server.crt\" --include \"server.key\" --include \"dh2048.pem\"\n chmod -R 0600 /etc/openvpn/keys\n aws s3 cp s3://", | |
{ | |
"Ref": "S3VpnKeysBucketName" | |
}, | |
"/server.conf /etc/openvpn\n aws s3 cp s3://", | |
{ | |
"Ref": "S3VpnKeysBucketName" | |
}, | |
"/ldap.conf /etc/openvpn\n\n cat <<EOT >/etc/pam.d/openvpn\nauth sufficient pam_ldap.so config=/etc/openvpn/ldap.conf\nauth required pam_deny.so\naccount required pam_ldap.so config=/etc/openvpn/ldap.conf\naccount required pam_permit.so\nEOT\n\n DEBIAN_FRONTEND=noninteractive apt-get install -y libpam-ldap\n\n apt-get install -y openvpn \n systemctl start openvpn@server\n\n echo \"=== Boostrap complete \"\n}\n\nbase 2>&1 | tee /tmp/bootstrap.log\n" | |
] | |
] | |
} | |
} | |
}, | |
"Type": "AWS::AutoScaling::LaunchConfiguration" | |
}, | |
"BastionRole": { | |
"Properties": { | |
"AssumeRolePolicyDocument": { | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Effect": "Allow", | |
"Principal": { | |
"Service": "ec2.amazonaws.com" | |
} | |
} | |
] | |
}, | |
"Path": "/" | |
}, | |
"Type": "AWS::IAM::Role" | |
}, | |
"BastionSG": { | |
"Properties": { | |
"GroupDescription": "BastionSecurityGroup", | |
"SecurityGroupIngress": [ | |
{ | |
"CidrIp": { | |
"Ref": "OfficeNetwork" | |
}, | |
"FromPort": 1194, | |
"IpProtocol": "udp", | |
"ToPort": 1194 | |
} | |
], | |
"VpcId": { | |
"Ref": "VpcId" | |
} | |
}, | |
"Type": "AWS::EC2::SecurityGroup" | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment