first commit
commit
c1d37d5170
|
@ -0,0 +1,4 @@
|
|||
.terraform/*
|
||||
.terraform.lock.hcl
|
||||
*.tfplan
|
||||
*.ovpn
|
|
@ -0,0 +1,56 @@
|
|||
BACKEND_CONFIG:=backend.tfvars
|
||||
TERRAFORM_PLAN:=out.tfplan
|
||||
OVPN_CONFIG:=aws_vpn.ovpn
|
||||
|
||||
## TERM COLORS
|
||||
GREEN=\033[0;32m
|
||||
RED=\033[0;31m
|
||||
YELLOW=\033[0;33m
|
||||
NC=\033[0m
|
||||
|
||||
all: help
|
||||
|
||||
.PHONY: help
|
||||
## print help
|
||||
help:
|
||||
@awk '/^#/{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' $(MAKEFILE_LIST) | column -s: -t
|
||||
|
||||
.PHONY: check_var
|
||||
check_var:
|
||||
ifndef REGION
|
||||
$(error "REGION is undefined")
|
||||
endif
|
||||
|
||||
.PHONY: init
|
||||
## init terraform backend and providers
|
||||
init: .terraform.lock.hcl
|
||||
|
||||
.terraform.lock.hcl: $(wildcard *.tf) $(wildcard *.tfvars)
|
||||
@terraform init -reconfigure -backend-config $(BACKEND_CONFIG)
|
||||
|
||||
.PHONY: plan
|
||||
## plan terraform changes
|
||||
plan: init $(TERRAFORM_PLAN)
|
||||
|
||||
$(TERRAFORM_PLAN): $(wildcard *.tf) $(wildcard *.tfvars)
|
||||
@terraform plan -var="region=$(REGION)" -var="ovpn_config_file=$(OVPN_CONFIG)" -input=false -out=$@
|
||||
|
||||
.PHONY: deploy
|
||||
## deploy the component
|
||||
deploy: plan
|
||||
@terraform apply -input=false $(TERRAFORM_PLAN) || (rm $(TERRAFORM_PLAN) && exit 1)
|
||||
|
||||
.PHONY: destroy
|
||||
## destroy the component deployment
|
||||
destroy: init
|
||||
@terraform destroy -auto-approve -var="region=$(REGION)"
|
||||
@rm $(TERRAFORM_PLAN) $(OVPN_CONFIG)
|
||||
|
||||
## clean builds and plan
|
||||
clean:
|
||||
@rm -rf $(TERRAFORM_PLAN) $(OVPN_CONFIG) .terraform .terraform.lock.hcl
|
||||
|
||||
.PHONY: format
|
||||
## format terraform code
|
||||
format:
|
||||
terraform fmt -recursive
|
|
@ -0,0 +1,11 @@
|
|||
# terraform-aws-ovpn-server
|
||||
Terraform code to deploy a temporary openvpn server in a specified region only accessible from the local public IP.
|
||||
|
||||
## Getting started
|
||||
### help
|
||||
`make help` will print the available makefile rules.
|
||||
### deploy
|
||||
`make deploy REGION=<aws-region>`
|
||||
The provider will use the current aws profile, set a profile with sufficient permissions.
|
||||
### use the vpn
|
||||
After the deployment you shoud get a `aws_vpn.ovpn` configuration file, import it to your VPN client (Tunnelblick for example) to connect to the VPN server.
|
|
@ -0,0 +1,5 @@
|
|||
acl = "bucket-owner-full-control"
|
||||
bucket = "coincoin-terraform-states"
|
||||
region = "eu-west-1"
|
||||
key = "openvpn_server.tfstate"
|
||||
dynamodb_table = "coincoin-terraform-states"
|
|
@ -0,0 +1,3 @@
|
|||
data "http" "myip" {
|
||||
url = "http://ipv4.icanhazip.com"
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
data "aws_ssm_parameter" "ubuntu_ami" {
|
||||
name = "/aws/service/canonical/ubuntu/server/20.04/stable/current/arm64/hvm/ebs-gp2/ami-id"
|
||||
}
|
||||
|
||||
data "template_file" "user_data" {
|
||||
template = file("${path.module}/user_data.tpl")
|
||||
vars = {
|
||||
s3_bucket = "${aws_s3_bucket.openvpn_config_bucket.bucket}"
|
||||
ovpn_config_file = "${var.ovpn_config_file}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "openvpn_sg" {
|
||||
name = "openvpn_sg"
|
||||
|
||||
ingress {
|
||||
from_port = 1194
|
||||
to_port = 1194
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["${chomp(data.http.myip.response_body)}/32"]
|
||||
}
|
||||
|
||||
egress {
|
||||
protocol = "-1"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "openvpn_server_ec2" {
|
||||
ami = data.aws_ssm_parameter.ubuntu_ami.value
|
||||
instance_type = "t4g.micro"
|
||||
tags = {
|
||||
Name = "openvpn_ephemeral_server"
|
||||
}
|
||||
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
|
||||
vpc_security_group_ids = [aws_security_group.openvpn_sg.id]
|
||||
|
||||
user_data = data.template_file.user_data.rendered
|
||||
}
|
||||
|
||||
resource "null_resource" "obtain_ovpn_file" {
|
||||
depends_on = [aws_instance.openvpn_server_ec2]
|
||||
provisioner "local-exec" {
|
||||
command = "export AWS_DEFAULT_REGION=${var.region}; rm -f *.ovpn; until aws s3 cp s3://${aws_s3_bucket.openvpn_config_bucket.bucket}/${var.ovpn_config_file} . > /dev/null 2>&1; do sleep 5; done;"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
resource "aws_iam_role" "ec2_role" {
|
||||
name = "ec2_role_${var.region}"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "ec2_profile" {
|
||||
name = "ec2_profile_${var.region}"
|
||||
role = aws_iam_role.ec2_role.name
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "ec2_policy" {
|
||||
name = "ec2_policy_${var.region}"
|
||||
role = aws_iam_role.ec2_role.id
|
||||
|
||||
policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [
|
||||
{
|
||||
Action = [
|
||||
"s3:ListBucket"
|
||||
]
|
||||
Effect = "Allow"
|
||||
Resource = "arn:aws:s3:::${aws_s3_bucket.openvpn_config_bucket.bucket}"
|
||||
},
|
||||
{
|
||||
Action = [
|
||||
"s3:PutObject",
|
||||
"s3:GetObject",
|
||||
"s3:DeleteObject"
|
||||
]
|
||||
Effect = "Allow"
|
||||
Resource = "arn:aws:s3:::${aws_s3_bucket.openvpn_config_bucket.bucket}/*"
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
terraform {
|
||||
required_version = ">= 1.0.0"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 4.0"
|
||||
}
|
||||
http = {
|
||||
source = "hashicorp/http"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
template = {
|
||||
source = "hashicorp/template"
|
||||
version = "~> 2.0"
|
||||
}
|
||||
}
|
||||
backend "s3" {}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
}
|
||||
|
||||
data "aws_caller_identity" "current" {}
|
|
@ -0,0 +1,9 @@
|
|||
output "instance_id" {
|
||||
description = "EC2 instance id of openvpn server"
|
||||
value = aws_instance.openvpn_server_ec2.id
|
||||
}
|
||||
|
||||
output "bucket_name" {
|
||||
description = "bucket name created by Terraform"
|
||||
value = aws_s3_bucket.openvpn_config_bucket.bucket
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
resource "aws_s3_bucket" "openvpn_config_bucket" {
|
||||
force_destroy = true
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_ownership_controls" "openvpn_config_bucket" {
|
||||
bucket = aws_s3_bucket.openvpn_config_bucket.id
|
||||
rule {
|
||||
object_ownership = "BucketOwnerPreferred"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_acl" "openvpn_config_bucket" {
|
||||
depends_on = [aws_s3_bucket_ownership_controls.openvpn_config_bucket]
|
||||
bucket = aws_s3_bucket.openvpn_config_bucket.id
|
||||
acl = "private"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#! /bin/bash
|
||||
apt-get update
|
||||
apt-get install awscli -y
|
||||
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
|
||||
chmod +x openvpn-install.sh
|
||||
APPROVE_INSTALL=y ENDPOINT=$(curl "http://169.254.169.254/latest/meta-data/public-ipv4") APPROVE_IP=y IPV6_SUPPORT=n PORT_CHOICE=1 PROTOCOL_CHOICE=1 DNS=1 COMPRESSION_ENABLED=n CUSTOMIZE_ENC=n CLIENT=openvpn PASS=1 ./openvpn-install.sh
|
||||
mv /root/openvpn.ovpn /tmp/${ovpn_config_file}
|
||||
chown ubuntu: /tmp/${ovpn_config_file}
|
||||
chmod 777 /tmp/${ovpn_config_file}
|
||||
aws s3 cp /tmp/${ovpn_config_file} s3://${s3_bucket}/
|
|
@ -0,0 +1,9 @@
|
|||
variable "region" {
|
||||
type = string
|
||||
description = "region to deploy openvpn ec2 resource"
|
||||
}
|
||||
|
||||
variable "ovpn_config_file" {
|
||||
type = string
|
||||
description = "name of the ovpn config file"
|
||||
}
|
Loading…
Reference in New Issue