Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
leventyalcin committed Jun 2, 2017
0 parents commit 2fd40ea
Show file tree
Hide file tree
Showing 6 changed files with 496 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.tfstate
*.tfstate.backup

.terraform/
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Warning
This module has not been tested yet. Start to use after it is tagged.

# Overview
This module setups a VPN server for a VPC to connect to instances

*Before you start to use the module you have to make sure you've created resources below*

* healthchecks.io account and cron entry for monitoring the backup script

After provisioning, don't forget to run commands below:

* **credstash**
* `export BACKUP_ENCRYPTION_KEY=$(uuidgen)`
* `credstash -r REGION -t CREDSTASH_TABLE_NAME put -k alias/CREDSTASH_TABLE_NAME BACKUP_ENCRYPTION_KEY $BACKUP_ENCRYPTION_KEY`
* `credstash -r REGION -t CREDSTASH_TABLE_NAME put -k alias/CREDSTASH_TABLE_NAME HEALTHCHECKS_IO_KEY CHANGEME-WITH-THE-KEY-FROM-HEALTHCHECKS-IO`

# Input variables

* **aws_key_name:** SSH Key pair for VPN instance
* **vpc_id:** The VPC id
* **public_subnet_id:** One of the public subnets to create the instance
* **ami_id:** Amazon Linux AMI ID
* **instance_type:** Instance type of the VPN box (t2.small is mostly enough)
* **office_ip_cidrs:** List of office IP addresses that you can SSH and non-VPN connected users can reach temporary profile download pages
* AWS Tags
* **tag_product**
* **tag_env**
* **tag_purpose**
* **tag_role**
# Outputs
* **vpn_instance_private_ip_address:** Private IP address of the instance
* **vpn_public_ip_addres:** EIP of the VPN box


# Usage

```
provider "aws" {
region = "eu-west-1"
}
data "aws_caller_identity" "current" { }
module "credstash" {
source = "github.com/opsgang/terraform_credstash?ref=1.0.0"
product = "vpn"
env = "dev"
aws_account_id = "${data.aws_caller_identity.current.account_id}"
}
module "app_pritunl" {
source = "github.com/opsgang/terraform_pritunl?ref=1.0.0"
aws_key_name = "vpn-ssh-key"
vpc_id = "vpc-99999999"
public_subnet_id = "subnet-99999999"
ami_id = "ami-99999999"
instance_type = "t2.small"
office_ip_cidrs = [
"8.8.8.8/32"
]
tag_product = "vpn"
tag_env = "dev"
tag_purpose = "networking"
tag_role = "vpn"
}
```

**P.S. :** Yes, AMI id is hardcoded! This module meant to be used in your VPC template. Presumably, no one wants to destroy the VPN instance and restore the configuration after `terraform apply` against to VPC. There is no harm to manage that manually and keep people working during the day.

*There will be wiki link about initial setup of Pritunl*
289 changes: 289 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
data "aws_region" "current" {
current = true
}

data "template_file" "user_data" {
template = "${file("${path.module}/templates/user_data.sh.tpl")}"

vars {
aws_region = "${aws_region.current.name}"
s3_backup_bucket = "${var.tag_product}-${var.tag_env}-backup"
credstash_table_name = "credstash-${var.tag_product}-${var.tag_env}"
}
}

resource "aws_s3_bucket" "backup" {
bucket = "${var.tag_product}-${var.tag_env}-backup"
acl = "private"

lifecycle_rule {
prefix = "backups"
enabled = true

expiration {
days = 30
}

abort_incomplete_multipart_upload_days = 7
}

tags {
Name = "${var.tag_product}-${var.tag_env}-backup"
product = "${var.tag_product}"
env = "${var.tag_env}"
purpose = "${var.tag_purpose}"
role = "${var.tag_role}"
}
}

# ec2 iam role
resource "aws_iam_role" "role" {
name = "${var.tag_product}-${var.tag_env}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "policy" {

depends_on = ["aws_iam_role.role"]

name = "${var.tag_product}-${var.tag_env}"
role = "${aws_iam_role.role.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:*",
"dynamodb:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [ "arn:aws:s3:::${var.tag_product}-${var.tag_env}-backup" ]
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:PutObject*",
"s3:Get*",
"s3:List*",
"s3:DeleteObject"
],
"Resource": [ "arn:aws:s3:::${var.tag_product}-${var.tag_env}-backup/*" ]
},
{
"Effect": "Allow",
"Action": [
"ssm:DescribeAssociation",
"ssm:GetDocument",
"ssm:ListAssociations",
"ssm:UpdateAssociationStatus",
"ssm:UpdateInstanceInformation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2messages:AcknowledgeMessage",
"ec2messages:DeleteMessage",
"ec2messages:FailMessage",
"ec2messages:GetEndpoint",
"ec2messages:GetMessages",
"ec2messages:SendReply"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstanceStatus"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ds:CreateComputer",
"ds:DescribeDirectories"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
EOF
}

resource "aws_iam_instance_profile" "ec2_profile" {

depends_on = ["aws_iam_role.role", "aws_iam_role_policy.policy"]

name = "${var.tag_product}-${var.tag_env}"
roles = ["${aws_iam_role.role.name}"]
}

resource "aws_security_group" "pritunl" {
name = "${var.tag_product}-${var.tag_env}-pritunl-vpn"
description = "${var.tag_product}-${var.tag_env}-pritunl-vpn"
vpc_id = "${var.vpc_id}"

# SSH access
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}

# HTTP access
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}

# VPN WAN access
ingress {
from_port = 10000
to_port = 19999
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}

# ICMP
ingress {
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["10.0.0.0/8"]
}

# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags {
Name = "${var.tag_product}-${var.tag_env}-pritunl-vpn"
product = "${var.tag_product}"
env = "${var.tag_env}"
purpose = "${var.tag_purpose}"
role = "${var.tag_role}"
}
}

resource "aws_security_group" "allow_from_office" {
name = "${var.tag_product}-${var.tag_env}-allow-from-office"
description = "Allows SSH connections and HTTP(s) connections from office"
vpc_id = "${var.vpc_id}"

# SSH access
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["${var.office_ip_cidrs}"]
}

# HTTP access
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["${var.office_ip_cidrs}"]
}

# ICMP
ingress {
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["${var.office_ip_cidrs}"]
}

# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags {
Name = "${var.tag_product}-${var.tag_env}-allow-from-office"
product = "${var.tag_product}"
env = "${var.tag_env}"
purpose = "${var.tag_purpose}"
role = "${var.tag_role}"
}
}

resource "aws_instance" "pritunl" {
ami = "${var.ami_id}"
instance_type = "${var.instance_type}"
key_name = "${var.aws_key_name}"
user_data = "${data.template_file.user_data.rendered}"
vpc_security_group_ids = [
"${aws_security_group.pritunl.id}",
"${aws_security_group.allow_from_office.id}"
]
subnet_id = "${var.public_subnet_id}"
iam_instance_profile = "${aws_iam_instance_profile.ec2_profile.name}"

tags {
Name = "${var.tag_product}-${var.tag_env}-vpn"
product = "${var.tag_product}"
env = "${var.tag_env}"
purpose = "${var.tag_purpose}"
role = "${var.tag_role}"
}
}

resource "aws_eip" "pritunl" {
instance = "${aws_instance.pritunl.id}"
vpc = true
}
7 changes: 7 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "vpn_instance_private_ip_address" {
value = "${aws_instance.pritunl.private_ip}"
}

output "vpn_public_ip_addres" {
value = "${aws_eip.pritunl.public_ip}"
}
Loading

0 comments on commit 2fd40ea

Please sign in to comment.