first commit

main
flavien 2023-10-19 20:09:30 +08:00
commit c1d37d5170
No known key found for this signature in database
12 changed files with 252 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.terraform/*
.terraform.lock.hcl
*.tfplan
*.ovpn

56
Makefile Normal file
View File

@ -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

11
README.md Normal file
View File

@ -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.

5
backend.tfvars Normal file
View File

@ -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"

3
data.tf Normal file
View File

@ -0,0 +1,3 @@
data "http" "myip" {
url = "http://ipv4.icanhazip.com"
}

49
ec2.tf Normal file
View File

@ -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;"
}
}

52
iam.tf Normal file
View File

@ -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}/*"
},
]
})
}

28
main.tf Normal file
View File

@ -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" {}

9
outputs.tf Normal file
View File

@ -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
}

16
s3.tf Normal file
View File

@ -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"
}

10
user_data.tpl Normal file
View File

@ -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}/

9
variables.tf Normal file
View File

@ -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"
}