auto region selection, more variables available

main
flavien 2023-10-22 19:18:21 +02:00
parent 244826303a
commit 4f9ecd66fc
No known key found for this signature in database
8 changed files with 68 additions and 28 deletions

3
.gitignore vendored
View File

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

View File

@ -1,6 +1,22 @@
BACKEND_CONFIG:=backend.tfvars
TERRAFORM_PLAN:=out.tfplan
OVPN_CONFIG:=aws_vpn.ovpn
DEPLOYED_REGION_FILE:=.deployed_region
AWS_REGIONS_FILE:=aws_region.txt
INSTANCE_SIZE ?= micro
PUBLIC_IP ?= $(shell curl -s ifconfig.me)
## AWS_REGIONS_FILE must contain a list of AWS regions, in one line, separated by spaces
REGIONS := $(shell head -n 1 $(AWS_REGIONS_FILE))
## check if DEPLOYED_REGION_FILE exists, if it does, REGION must not be set
DEPLOYED_REGION_FILE_EXISTS := $(wildcard $(DEPLOYED_REGION_FILE))
ifneq ($(DEPLOYED_REGION_FILE_EXISTS),)
ifdef REGION
$(error REGION is manually set but $(DEPLOYED_REGION_FILE) exists, please destroy the existing deployment first)
endif
endif
## if REGION is not set, select a random region from AWS_REGIONS_FILE
REGION ?= $(word $(shell echo $$((RANDOM%$(words $(REGIONS))+1))), $(REGIONS))
## TERM COLORS
GREEN=\033[0;32m
@ -15,37 +31,49 @@ all: 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.lock.hcl: $(BACKEND_CONFIG) providers.tf
@rm -f $@
@terraform init -reconfigure -backend-config $(BACKEND_CONFIG)
.PHONY: plan
## plan terraform changes
plan: init check_var $(TERRAFORM_PLAN)
## plan terraform deployment in random region or REGION if set
plan: init $(TERRAFORM_PLAN)
$(TERRAFORM_PLAN): $(wildcard *.tf) $(wildcard *.tfvars)
@terraform plan -var="region=$(REGION)" -var="ovpn_config_file=$(OVPN_CONFIG)" -input=false -out=$@
$(TERRAFORM_PLAN): $(wildcard *.tf) $(DEPLOYED_REGION_FILE)
@echo "prepare deployment to region ${GREEN}$(shell head -n 1 $(DEPLOYED_REGION_FILE))${NC}..."
@terraform get -update
@terraform plan -var="region=$(shell head -n 1 $(DEPLOYED_REGION_FILE))" -var="ovpn_config_file=$(OVPN_CONFIG)" -var="instance_size=$(INSTANCE_SIZE)" -var="public_ip=$(PUBLIC_IP)" -input=false -out=$@
$(DEPLOYED_REGION_FILE):
@export SELECTED_REGION=$(REGION) && echo $$SELECTED_REGION > $@ && echo "selected region: ${GREEN}$$SELECTED_REGION${NC}"
@echo "deployment region saved to ${GREEN}$(DEPLOYED_REGION_FILE)${NC} file"
@echo "⚠️ ${YELLOW}warning:${NC} do not edit this file manually or delete it ⚠️"
.PHONY: deploy
## deploy the component
## deploy the server according to the plan
deploy: plan
@terraform apply -input=false $(TERRAFORM_PLAN) || (rm $(TERRAFORM_PLAN) && exit 1)
@echo "deploy server in region ${GREEN}$(shell head -n 1 $(DEPLOYED_REGION_FILE))${NC}..."
# always remove plan file after apply because... bug ? => always considered as stale if re-applied
@(terraform apply -input=false $(TERRAFORM_PLAN) && rm $(TERRAFORM_PLAN)) || (rm $(TERRAFORM_PLAN) && exit 1)
.PHONY: destroy
## destroy the component deployment
destroy: init check_var
@terraform destroy -auto-approve -var="region=$(REGION)" -var="ovpn_config_file=$(OVPN_CONFIG)"
@rm -f $(TERRAFORM_PLAN) $(OVPN_CONFIG)
## destroy the server deployment
destroy: init $(DEPLOYED_REGION_FILE)
# allow destroying mannually selected REGION if deployed region file is accidentally deleted
ifneq ($(DEPLOYED_REGION_FILE_EXISTS),)
@echo "destroy server in region ${GREEN}$(shell head -n 1 $(DEPLOYED_REGION_FILE))${NC}"
@terraform destroy -auto-approve -var="region=$(shell head -n 1 $(DEPLOYED_REGION_FILE))" -var="ovpn_config_file=$(OVPN_CONFIG)" -var="instance_size=$(INSTANCE_SIZE)" -var="public_ip=$(PUBLIC_IP)"
else
@echo "destroy server in region ${GREEN}$(REGION)${NC}"
@terraform destroy -auto-approve -var="region=$(REGION)" -var="ovpn_config_file=$(OVPN_CONFIG)" -var="instance_size=$(INSTANCE_SIZE)" -var="public_ip=$(PUBLIC_IP)"
endif
@rm -f $(TERRAFORM_PLAN) $(OVPN_CONFIG) $(DEPLOYED_REGION_FILE)
.PHONY: clean
## clean builds and plan
clean:
@rm -rf $(TERRAFORM_PLAN) $(OVPN_CONFIG) .terraform .terraform.lock.hcl

View File

@ -5,7 +5,11 @@ Terraform code to deploy a temporary openvpn server in a specified region only a
### help
`make help` will print the available makefile rules.
### deploy
`make deploy REGION=<aws-region>`
`make deploy REGION=<aws-region> INSTANCE_SIZE=<nano/micro/...>`
The provider will use the current aws profile, set a profile with sufficient permissions.
If REGION is not set, a random region is selected from the regions declared in the file `aws_regions.txt`.
If INSTANCE_SIZE is not set, will use `micro` by default.
PUBLIC_IP can be set manually but is set by default to your current public ip.
Once a region selected for a deployment it is saved in a `.deployed_region` file, to not edit manually or deleted or you will lost the tracking a the currently deployed region.
### 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.

1
aws_region.txt Normal file
View File

@ -0,0 +1 @@
us-east-1 us-east-2 us-west-1 us-west-2 eu-west-1 eu-west-2 eu-west-3 eu-central-1 eu-north-1 eu-south-1 ap-south-1 ap-northeast-1 ap-northeast-2 ap-southeast-1 ap-southeast-2 ap-east-1

View File

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

7
ec2.tf
View File

@ -9,7 +9,7 @@ resource "aws_security_group" "openvpn_sg" {
from_port = 1194
to_port = 1194
protocol = "udp"
cidr_blocks = ["${chomp(data.http.myip.response_body)}/32"]
cidr_blocks = ["${var.public_ip}/32"]
}
egress {
@ -22,7 +22,7 @@ resource "aws_security_group" "openvpn_sg" {
resource "aws_instance" "openvpn_server_ec2" {
ami = data.aws_ssm_parameter.ubuntu_ami.value
instance_type = "t4g.micro"
instance_type = "t4g.${var.instance_size}"
tags = {
Name = "openvpn_ephemeral_server"
}
@ -37,8 +37,9 @@ resource "aws_instance" "openvpn_server_ec2" {
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;"
}
}

View File

@ -20,5 +20,3 @@ terraform {
provider "aws" {
region = var.region
}
data "aws_caller_identity" "current" {}

View File

@ -1,9 +1,19 @@
variable "region" {
type = string
description = "region to deploy openvpn ec2 resource"
description = "region to deploy openvpn server"
}
variable "instance_size" {
type = string
description = "ec2 instance size to deploy openvpn server"
}
variable "ovpn_config_file" {
type = string
description = "name of the ovpn config file"
}
variable "public_ip" {
type = string
description = "public ip of the client"
}