From d9077dabe2ef249708e6e626901a2815d1221fb8 Mon Sep 17 00:00:00 2001 From: be99inner Date: Thu, 17 Nov 2022 10:40:16 +0700 Subject: [PATCH 01/23] refact: cleanup codes --- autoscaling.tf | 40 ------ efs.tf | 30 ----- launch-template.tf | 19 --- main.tf | 175 +++++++++++++++++++++++++++ route53.tf | 28 ----- sg.tf | 37 ------ {template => templates}/user_data.sh | 0 7 files changed, 175 insertions(+), 154 deletions(-) delete mode 100644 autoscaling.tf delete mode 100644 efs.tf delete mode 100644 launch-template.tf delete mode 100644 route53.tf delete mode 100644 sg.tf rename {template => templates}/user_data.sh (100%) diff --git a/autoscaling.tf b/autoscaling.tf deleted file mode 100644 index e7dcc00..0000000 --- a/autoscaling.tf +++ /dev/null @@ -1,40 +0,0 @@ -# Auto Scaling Group -resource "aws_autoscaling_group" "this" { - name_prefix = local.name - vpc_zone_identifier = var.private_subnet_ids - desired_capacity = 1 - max_size = 1 #fix 1 to avoid race condition (if not move to document db for multi read/write) - min_size = 1 - - launch_template { - id = module.launch_template.id - version = "$Latest" - } - - target_group_arns = concat(aws_lb_target_group.public.*.arn, aws_lb_target_group.private.*.arn) - dynamic "tag" { - for_each = merge(local.tags, { Name = local.name }) - content { - key = tag.key - value = tag.value - propagate_at_launch = true - } - } - - lifecycle { - create_before_destroy = true - } -} - - -resource "aws_autoscaling_policy" "this" { - name = "pritunl-vpn-auto-scaling-policy" - policy_type = "TargetTrackingScaling" - autoscaling_group_name = aws_autoscaling_group.this.name - target_tracking_configuration { - predefined_metric_specification { - predefined_metric_type = "ASGAverageCPUUtilization" - } - target_value = 50.0 - } -} diff --git a/efs.tf b/efs.tf deleted file mode 100644 index 4502a90..0000000 --- a/efs.tf +++ /dev/null @@ -1,30 +0,0 @@ -# EFS -module "efs" { - source = "oozou/efs/aws" - version = "1.0.4" - - prefix = var.prefix - environment = var.environment - name = "pritunl-data" - encrypted = true - enabled_backup = var.enabled_backup - efs_backup_policy_enabled = var.efs_backup_policy_enabled - access_points = { - "data" = { - posix_user = { - gid = "1001" - uid = "5000" - secondary_gids = "1002,1003" - } - creation_info = { - gid = "1001" - uid = "5000" - permissions = "0755" - } - } - } - vpc_id = var.vpc_id - subnets = var.private_subnet_ids - - additional_efs_resource_policies = [] -} diff --git a/launch-template.tf b/launch-template.tf deleted file mode 100644 index 295bdeb..0000000 --- a/launch-template.tf +++ /dev/null @@ -1,19 +0,0 @@ -# Launch Configuration Template -module "launch_template" { - source = "oozou/launch-template/aws" - version = "1.0.3" - prefix = var.prefix - environment = var.environment - name = "pritunl-vpn" - user_data = base64encode(templatefile("${path.module}/template/user_data.sh", - { - efs_id = module.efs.id - })) - iam_instance_profile = { arn : aws_iam_instance_profile.this.arn } - ami_id = var.ami == "" ? data.aws_ami.amazon_linux.id : var.ami - key_name = var.key_name - instance_type = var.instance_type - vpc_security_group_ids = local.security_group_ids - enable_monitoring = var.enable_ec2_monitoring - tags = local.tags -} diff --git a/main.tf b/main.tf index e69de29..d739cc7 100644 --- a/main.tf +++ b/main.tf @@ -0,0 +1,175 @@ +# ############################################################################# +# EFS Storage +# ############################################################################# +module "efs" { + source = "oozou/efs/aws" + version = "1.0.4" + + prefix = var.prefix + environment = var.environment + name = "pritunl-data" + encrypted = true + enabled_backup = var.enabled_backup + efs_backup_policy_enabled = var.efs_backup_policy_enabled + access_points = { + "data" = { + posix_user = { + gid = "1001" + uid = "5000" + secondary_gids = "1002,1003" + } + creation_info = { + gid = "1001" + uid = "5000" + permissions = "0755" + } + } + } + vpc_id = var.vpc_id + subnets = var.private_subnet_ids + + additional_efs_resource_policies = [] + + tags = var.tags +} + +# ############################################################################# +# Security Groups +# ############################################################################# +resource "aws_security_group" "this" { + count = var.is_create_security_group ? 1 : 0 + + name_prefix = format("%s-ec2-sg", local.name) + vpc_id = var.vpc_id + description = "Pritunl VPN egress rule for outbound" + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + tags = merge( + local.tags, + { "Name" = format("%s-ec2-sg", local.name) }, + ) +} + +resource "aws_security_group_rule" "ingress" { + for_each = var.is_create_security_group ? local.security_group_ingress_rules : null + + type = "ingress" + from_port = lookup(each.value, "from_port", lookup(each.value, "port", null)) + to_port = lookup(each.value, "to_port", lookup(each.value, "port", null)) + protocol = lookup(each.value, "protocol", "tcp") + security_group_id = aws_security_group.this[0].id + + cidr_blocks = lookup(each.value, "cidr_blocks", null) + description = lookup(each.value, "description", null) + ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null) + prefix_list_ids = lookup(each.value, "prefix_list_ids", null) + source_security_group_id = lookup(each.value, "source_security_group_id", null) +} + +# ############################################################################# +# Laucn Template +# ############################################################################# +module "launch_template" { + source = "oozou/launch-template/aws" + version = "1.0.3" + prefix = var.prefix + environment = var.environment + name = "pritunl-vpn" + user_data = base64encode(templatefile("${path.module}/templates/user_data.sh", + { + efs_id = module.efs.id + })) + iam_instance_profile = { arn : aws_iam_instance_profile.this.arn } + ami_id = var.ami == "" ? data.aws_ami.amazon_linux.id : var.ami + key_name = var.key_name + instance_type = var.instance_type + vpc_security_group_ids = local.security_group_ids + enable_monitoring = var.enable_ec2_monitoring + tags = local.tags +} + +# ############################################################################# +# AutoScaling Group +# ############################################################################# +resource "aws_autoscaling_group" "this" { + name_prefix = local.name + vpc_zone_identifier = var.private_subnet_ids + desired_capacity = 1 + max_size = 1 #fix 1 to avoid race condition (if not move to document db for multi read/write) + min_size = 1 + + launch_template { + id = module.launch_template.id + version = "$Latest" + } + + target_group_arns = concat(aws_lb_target_group.public[*].arn, aws_lb_target_group.private[*].arn) + dynamic "tag" { + for_each = merge(local.tags, { Name = local.name }) + content { + key = tag.key + value = tag.value + propagate_at_launch = true + } + } + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_autoscaling_policy" "this" { + name = "pritunl-vpn-auto-scaling-policy" + policy_type = "TargetTrackingScaling" + autoscaling_group_name = aws_autoscaling_group.this.name + target_tracking_configuration { + predefined_metric_specification { + predefined_metric_type = "ASGAverageCPUUtilization" + } + target_value = 50.0 + } +} + +# ############################################################################# +# Load Balancer +# ############################################################################# + + +# ############################################################################# +# DNS Records +# ############################################################################# +data "aws_route53_zone" "this" { + count = var.is_create_route53_reccord ? 1 : 0 + name = var.route53_zone_name +} + +resource "aws_route53_record" "public" { + count = var.is_create_route53_reccord ? 1 : 0 + zone_id = data.aws_route53_zone.this[0].zone_id + name = format("%s.%s", var.public_lb_vpn_domain, var.route53_zone_name) + type = "A" + alias { + name = aws_lb.public.dns_name + zone_id = aws_lb.public.zone_id + evaluate_target_health = true + } +} + +resource "aws_route53_record" "private" { + count = var.is_create_private_lb && var.is_create_route53_reccord ? 1 : 0 + zone_id = data.aws_route53_zone.this[0].zone_id + name = format("%s.%s", var.private_lb_vpn_domain, var.route53_zone_name) + type = "A" + alias { + name = aws_lb.private[0].dns_name + zone_id = aws_lb.private[0].zone_id + evaluate_target_health = true + } +} diff --git a/route53.tf b/route53.tf deleted file mode 100644 index c2cc8f4..0000000 --- a/route53.tf +++ /dev/null @@ -1,28 +0,0 @@ -data "aws_route53_zone" "this" { - count = var.is_create_route53_reccord ? 1 : 0 - name = var.route53_zone_name -} - -resource "aws_route53_record" "public" { - count = var.is_create_route53_reccord ? 1 : 0 - zone_id = data.aws_route53_zone.this[0].zone_id - name = format("%s.%s", var.public_lb_vpn_domain, var.route53_zone_name) - type = "A" - alias { - name = aws_lb.public.dns_name - zone_id = aws_lb.public.zone_id - evaluate_target_health = true - } -} - -resource "aws_route53_record" "private" { - count = var.is_create_private_lb && var.is_create_route53_reccord ? 1 : 0 - zone_id = data.aws_route53_zone.this[0].zone_id - name = format("%s.%s", var.private_lb_vpn_domain, var.route53_zone_name) - type = "A" - alias { - name = aws_lb.private[0].dns_name - zone_id = aws_lb.private[0].zone_id - evaluate_target_health = true - } -} diff --git a/sg.tf b/sg.tf deleted file mode 100644 index 1739694..0000000 --- a/sg.tf +++ /dev/null @@ -1,37 +0,0 @@ -# Security Group -resource "aws_security_group" "this" { - count = var.is_create_security_group ? 1 : 0 - - name_prefix = format("%s-ec2-sg", local.name) - vpc_id = var.vpc_id - description = "Pritunl VPN egress rule for outbound" - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - } - - tags = merge( - local.tags, - { "Name" = format("%s-ec2-sg", local.name) }, - ) -} - -resource "aws_security_group_rule" "ingress" { - for_each = var.is_create_security_group ? local.security_group_ingress_rules : null - - type = "ingress" - from_port = lookup(each.value, "from_port", lookup(each.value, "port", null)) - to_port = lookup(each.value, "to_port", lookup(each.value, "port", null)) - protocol = lookup(each.value, "protocol", "tcp") - security_group_id = aws_security_group.this[0].id - - cidr_blocks = lookup(each.value, "cidr_blocks", null) - description = lookup(each.value, "description", null) - ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null) - prefix_list_ids = lookup(each.value, "prefix_list_ids", null) - source_security_group_id = lookup(each.value, "source_security_group_id", null) -} diff --git a/template/user_data.sh b/templates/user_data.sh similarity index 100% rename from template/user_data.sh rename to templates/user_data.sh From 81e1946e15dc3352e9d2892a670d9094da9abd96 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 12:15:37 +0700 Subject: [PATCH 02/23] feat: enhance pritunl vpn function and bug fixes --- iam.tf | 62 -------------- main.tf | 91 ++++++++++++++++++++- templates/cloudwatch-agent-conf.json | 111 ++++++++++++++++++++++++++ templates/systemd-mongod-drop-in.conf | 3 + templates/user_data.sh | 52 +++++++++++- variables.tf | 6 ++ versions.tf | 4 + 7 files changed, 265 insertions(+), 64 deletions(-) delete mode 100644 iam.tf create mode 100644 templates/cloudwatch-agent-conf.json create mode 100644 templates/systemd-mongod-drop-in.conf diff --git a/iam.tf b/iam.tf deleted file mode 100644 index 9a431d4..0000000 --- a/iam.tf +++ /dev/null @@ -1,62 +0,0 @@ -data "aws_iam_policy_document" "this" { - statement { - sid = "IamPassRole" - actions = ["iam:PassRole"] - resources = ["*"] - condition { - test = "StringEquals" - variable = "iam:PassedToService" - values = ["ec2.amazonaws.com"] - } - } - statement { - sid = "ListEc2AndListInstanceProfiles" - actions = [ - "iam:ListInstanceProfiles", - "ec2:Describe*", - "ec2:Search*", - "ec2:Get*" - ] - resources = ["*"] - condition { - test = "StringEquals" - variable = "iam:PassedToService" - values = ["ec2.amazonaws.com"] - } - } -} - -data "aws_iam_policy_document" "this_assume_role" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["ec2.amazonaws.com"] - } - } -} - -resource "aws_iam_role" "this" { - name = format("%s-role", local.name) - path = "/" - assume_role_policy = data.aws_iam_policy_document.this_assume_role.json -} - -resource "aws_iam_role_policy" "this" { - name = format("%s-policy", local.name) - role = aws_iam_role.this.id - - policy = data.aws_iam_policy_document.this.json -} - -resource "aws_iam_role_policy_attachment" "this" { - count = length(local.profile_policy_arns) - role = aws_iam_role.this.name - policy_arn = local.profile_policy_arns[count.index] -} - -resource "aws_iam_instance_profile" "this" { - name = format("%s-profile", local.name) - role = aws_iam_role.this.name -} diff --git a/main.tf b/main.tf index d739cc7..b023021 100644 --- a/main.tf +++ b/main.tf @@ -73,6 +73,90 @@ resource "aws_security_group_rule" "ingress" { source_security_group_id = lookup(each.value, "source_security_group_id", null) } +# ############################################################################# +# Generate Data +# ############################################################################# +resource "random_string" "host_id" { + count = length(var.host_id) > 0 ? 0 : 1 + + numeric = true + lower = true + upper = false + length = 32 + special = false +} + +# ############################################################################# +# IAM Roles +# ############################################################################# +data "aws_iam_policy_document" "this" { + statement { + sid = "IamPassRole" + actions = ["iam:PassRole"] + resources = ["*"] + condition { + test = "StringEquals" + variable = "iam:PassedToService" + values = ["ec2.amazonaws.com"] + } + } + statement { + sid = "ListEc2AndListInstanceProfiles" + actions = [ + "iam:ListInstanceProfiles", + "ec2:Describe*", + "ec2:Search*", + "ec2:Get*" + ] + resources = ["*"] + condition { + test = "StringEquals" + variable = "iam:PassedToService" + values = ["ec2.amazonaws.com"] + } + } +} + +data "aws_iam_policy_document" "this_assume_role" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "this" { + name = format("%s-role", local.name) + path = "/" + assume_role_policy = data.aws_iam_policy_document.this_assume_role.json +} + +resource "aws_iam_role_policy" "this" { + name = format("%s-policy", local.name) + role = aws_iam_role.this.id + + policy = data.aws_iam_policy_document.this.json +} + +resource "aws_iam_role_policy_attachment" "this" { + count = length(local.profile_policy_arns) + role = aws_iam_role.this.name + policy_arn = local.profile_policy_arns[count.index] +} + +resource "aws_iam_instance_profile" "this" { + name = format("%s-profile", local.name) + role = aws_iam_role.this.name +} + +resource "aws_iam_role_policy_attachment" "cloudwatch_agent" { + role = aws_iam_role.this.name + policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" +} + # ############################################################################# # Laucn Template # ############################################################################# @@ -84,7 +168,12 @@ module "launch_template" { name = "pritunl-vpn" user_data = base64encode(templatefile("${path.module}/templates/user_data.sh", { - efs_id = module.efs.id + efs_id = module.efs.id, + cloudwatch_agent_config_file = templatefile("${path.module}/templates/cloudwatch-agent-conf.json", { + cloudwatch_metric_namespace = "EC2/pritunl-vpn" + }), + mongodb_drop_in_service_file = file("${path.module}/templates/systemd-mongod-drop-in.conf"), + pritunl_host_id = length(var.host_id) > 0 ? var.host_id : random_string.host_id[0].result })) iam_instance_profile = { arn : aws_iam_instance_profile.this.arn } ami_id = var.ami == "" ? data.aws_ami.amazon_linux.id : var.ami diff --git a/templates/cloudwatch-agent-conf.json b/templates/cloudwatch-agent-conf.json new file mode 100644 index 0000000..484e321 --- /dev/null +++ b/templates/cloudwatch-agent-conf.json @@ -0,0 +1,111 @@ +{ + "agent": { + "metrics_collection_interval": 10 + }, + "logs": { + "logs_collected": { + "files": { + "collect_list": [ + { + "file_path": "/var/log/messages", + "log_group_name": "/aws/ec2/pritunl-vpn", + "log_stream_name": "syslog", + "timestamp_format": "%H: %M: %S%y%b%-d" + }, + { + "file_path": "/var/log/pritunl.log", + "log_group_name": "/aws/ec2/pritunl-vpn", + "log_stream_name": "pritunl", + "timestamp_format": "%H: %M: %S%y%b%-d" + }, + { + "file_path": "/var/log/mongodb/mongod.log", + "log_group_name": "/aws/ec2/pritunl-vpn", + "log_stream_name": "mongod", + "timestamp_format": "%H: %M: %S%y%b%-d" + } + ] + } + } + }, + "metrics": { + "namespace": "${cloudwatch_metric_namespace}", + "append_dimensions": { + "AutoScalingGroupName": "$${aws:AutoScalingGroupName}", + "ImageId": "$${aws:ImageId}", + "InstanceId": "$${aws:InstanceId}", + "InstanceType": "$${aws:InstanceType}", + "InstanceRole": "gitlab-runner" + }, + "aggregation_dimensions": [ + [ + "InstanceType", + "AutoScalingGroupName" + ], + [ + "InstanceId", + "InstanceType" + ], + [ + "InstanceId" + ], + [ + "InstanceRole" + ] + ], + "metrics_collected": { + "cpu": { + "measurement": [ + "usage_idle", + "usage_iowait", + "usage_user", + "usage_system" + ] + }, + "disk": { + "resources": [ + "/", + "/tmp" + ], + "measurement": [ + "used_percent", + "inodes_free" + ], + "ignore_file_system_types": [ + "sysfs", + "devtmpfs" + ] + }, + "diskio": { + "measurement": [ + "io_time", + "write_bytes", + "read_bytes", + "writes", + "reads" + ] + }, + "mem": { + "measurement": [ + "available", + "available_percent", + "used", + "used_percent" + ] + }, + "netstat": { + "measurement": [ + "tcp_established", + "tcp_time_wait" + ] + }, + "swap": { + "measurement": [ + "used", + "free", + "used_percent" + ] + } + } + } +} diff --git a/templates/systemd-mongod-drop-in.conf b/templates/systemd-mongod-drop-in.conf new file mode 100644 index 0000000..ae58d81 --- /dev/null +++ b/templates/systemd-mongod-drop-in.conf @@ -0,0 +1,3 @@ +[Service] +Restart=on-failure +RestartSec=30s diff --git a/templates/user_data.sh b/templates/user_data.sh index e33ded8..fd4a1c7 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -1,5 +1,30 @@ -#!/bin/bash -x +#!/bin/bash -xe +# Redirect stdout from user_data to console log +# https://aws.amazon.com/premiumsupport/knowledge-center/ec2-linux-log-user-data/ +exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 + +echo "################################################################### +# Script Name : amazon-linux-pritunl-install.sh +# Description : Bootstrap Script to install PritunlVPN on Amazon Linux +# Args : +# Author : DevOps@OOZOU +# Email : devops@oozou.com +###################################################################" + +echo ">>> Installing CloudWatch Agent ..." +sudo yum install -y amazon-cloudwatch-agent +echo '${cloudwatch_agent_config_file}' > cloudwatch-agent-config.json +echo ">>> Reconfiguring CloudWatch Agent ..." +sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ +-a fetch-config \ +-m ec2 \ +-c file:cw-agent-config.json -s +echo ">>> Restarting amazon-cloudwatch-agent service..." +sudo systemctl restart amazon-cloudwatch-agent +sudo systemctl enable amazon-cloudwatch-agent + +echo ">>> Preparing OS to install PritunlVPN ..." sudo yum update -y sudo yum -y install wget if [[ "$(python3 -V 2>&1)" =~ ^(Python 3.6.*) ]]; then @@ -13,10 +38,15 @@ else fi sudo python3 /tmp/get-pip.py sudo /usr/local/bin/pip3 install botocore + +echo ">>> Installing EFS client for PritunlVPN data ..." sudo yum install -y amazon-efs-utils +echo ">>> Mounting EFS volume to instance ..." sudo mkdir /mnt/efs echo "${efs_id}:/ /mnt/efs efs _netdev,noresvport,tls,iam 0 0" | sudo tee -a /etc/fstab sudo mount -a + +echo ">>> Adding MongoDB Repository to package manager ..." sudo tee /etc/yum.repos.d/mongodb-org-5.0.repo << EOF [mongodb-org-5.0] name=MongoDB Repository @@ -25,6 +55,7 @@ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc EOF +echo ">>> Adding MongoDB Repository to package manager ..." sudo tee /etc/yum.repos.d/pritunl.repo << EOF [pritunl] name=Pritunl Repository @@ -32,20 +63,39 @@ baseurl=https://repo.pritunl.com/stable/yum/amazonlinux/2/ gpgcheck=1 enabled=1 EOF + +echo ">>> Adding Keys for package manager ..." sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 7568D9BB55FF9E5287D586017AE645C0CF8E292A gpg --armor --export 7568D9BB55FF9E5287D586017AE645C0CF8E292A > key.tmp; sudo rpm --import key.tmp; rm -f key.tmp +echo ">>> Installing PritunlVPN and MongoDB ..." sudo yum -y install pritunl mongodb-org-5.0.9-1.amzn2 +echo ">>> Setting up data volume for MongoDB ..." sudo sed -i.bak "s/\/var\/lib\/mongo/\/mnt\/efs/g" /etc/mongod.conf sudo chown -R mongod:mongod /mnt/efs/ +echo ">>> Setting up drop-in service for MongoDB" +# Auto Restart MongoDB to prevent it faile to start on the first time. +echo "${mongodb_drop_in_service_file}" | sudo tee /etc/systemd/system/mongod.d/10-auto-restart-on-failure.conf +sudo systemctl daemon-reload + +echo ">>> Starting MongoDB service ..." sudo systemctl start mongod pritunl sudo systemctl enable mongod pritunl + +echo ">>> Starting PritunlVPN service ..." +sudo systemctl start pritunl +sudo systemctl enable pritunl + +echo ">>> Reconfiguring PritunlVPN ..." +sudo pritunl set-host-id "${pritunl_host_id}" sudo pritunl set-mongodb mongodb://localhost:27017/pritunl sudo pritunl set app.redirect_server false sudo pritunl set app.server_ssl true sudo pritunl set app.server_port 443 sudo pritunl set app.www_path /usr/share/pritunl/www + +echo ">>> Reload PritunlVPN configuration ..." sudo systemctl restart pritunl diff --git a/variables.tf b/variables.tf index f7b9ed0..90139fb 100644 --- a/variables.tf +++ b/variables.tf @@ -159,3 +159,9 @@ variable "is_create_private_lb" { type = bool default = true } + +variable "host_id" { + description = "Override PritunlVPN host id with this option, Use with migration only" + type = string + default = "" +} diff --git a/versions.tf b/versions.tf index 521a51d..ee129e0 100644 --- a/versions.tf +++ b/versions.tf @@ -6,5 +6,9 @@ terraform { source = "hashicorp/aws" version = ">= 4.0.0" } + random = { + source = "hashicorp/random" + version = ">= 3.0.0" + } } } From cee538f44736d180d241f7d7fc16c4479f0e8b4a Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 12:16:01 +0700 Subject: [PATCH 03/23] chore: update docs --- README.md | 143 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 421a888..3f1c2a5 100644 --- a/README.md +++ b/README.md @@ -165,89 +165,94 @@ mongorestore /efs/dump ## Requirements -| Name | Version | -|---------------------------------------------------------------------------|----------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.0.0 | +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0.0 | +| [random](#requirement\_random) | >= 3.0.0 | ## Providers -| Name | Version | -|---------------------------------------------------|---------| -| [aws](#provider\_aws) | 4.36.0 | +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 4.19.0 | +| [random](#provider\_random) | 3.4.3 | ## Modules -| Name | Source | Version | -|-------------------------------------------------------------------------------------|---------------------------|---------| -| [efs](#module\_efs) | oozou/efs/aws | 1.0.4 | -| [launch\_template](#module\_launch\_template) | oozou/launch-template/aws | 1.0.3 | +| Name | Source | Version | +|------|--------|---------| +| [efs](#module\_efs) | oozou/efs/aws | 1.0.4 | +| [launch\_template](#module\_launch\_template) | oozou/launch-template/aws | 1.0.3 | ## Resources -| Name | Type | -|------------------------------------------------------------------------------------------------------------------------------------------------|-------------| -| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | -| [aws_autoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource | -| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | -| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | -| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_lb.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | -| [aws_lb.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | -| [aws_lb_listener.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | -| [aws_lb_listener.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | -| [aws_lb_target_group.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | -| [aws_lb_target_group.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | -| [aws_route53_record.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | -| [aws_route53_record.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | -| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | -| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| Name | Type | +|------|------| +| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | +| [aws_autoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource | +| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_iam_role_policy_attachment.cloudwatch_agent](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_lb.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | +| [aws_lb.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | +| [aws_lb_listener.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | +| [aws_lb_listener.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | +| [aws_lb_target_group.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_lb_target_group.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_route53_record.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_route53_record.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [random_string.host_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.this_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | -| [aws_vpc.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | +| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | +| [aws_vpc.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | ## Inputs -| Name | Description | Type | Default | Required | -|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:| -| [additional\_sg\_attacment\_ids](#input\_additional\_sg\_attacment\_ids) | (Optional) The ID of the security group. | `list(string)` | `[]` | no | -| [ami](#input\_ami) | (Optional) AMI to use for the instance. Required unless launch\_template is specified and the Launch Template specifes an AMI. If an AMI is specified in the Launch Template, setting ami will override the AMI specified in the Launch Template | `string` | `""` | no | -| [custom\_https\_allow\_cidr](#input\_custom\_https\_allow\_cidr) | cidr block for config pritunl vpn | `list(string)` | `null` | no | -| [efs\_backup\_policy\_enabled](#input\_efs\_backup\_policy\_enabled) | If `true`, it will turn on automatic backups. | `bool` | `true` | no | -| [enable\_ec2\_monitoring](#input\_enable\_ec2\_monitoring) | Enables/disables detailed monitoring | `bool` | `false` | no | -| [enabled\_backup](#input\_enabled\_backup) | Enable Backup EFS | `bool` | `true` | no | -| [environment](#input\_environment) | Environment Variable used as a prefix | `string` | n/a | yes | -| [instance\_type](#input\_instance\_type) | (Optional) The instance type to use for the instance. Updates to this field will trigger a stop/start of the EC2 instance. | `string` | `"t2.medium"` | no | -| [is\_create\_private\_lb](#input\_is\_create\_private\_lb) | if true this module will not create private lb for cost optimization | `bool` | `true` | no | -| [is\_create\_route53\_reccord](#input\_is\_create\_route53\_reccord) | if true will create route53 reccord for vpn, vpn console | `bool` | `false` | no | -| [is\_create\_security\_group](#input\_is\_create\_security\_group) | Flag to toggle security group creation | `bool` | `true` | no | -| [is\_enabled\_https\_public](#input\_is\_enabled\_https\_public) | if true will enable https to public loadbalancer else enable to private loadbalancer | `bool` | `true` | no | -| [key\_name](#input\_key\_name) | Key name of the Key Pair to use for the vpn instance; which can be managed using | `string` | `null` | no | -| [prefix](#input\_prefix) | The prefix name of customer to be displayed in AWS console and resource | `string` | n/a | yes | -| [private\_lb\_vpn\_domain](#input\_private\_lb\_vpn\_domain) | domain of vpn console output will be . | `string` | `"vpn-console"` | no | -| [private\_rule](#input\_private\_rule) | private rule for run connect vpn |
list(object({
port = number
protocol = string
health_check_port = number
health_check_protocol = string
}))
| `[]` | no | -| [private\_subnet\_ids](#input\_private\_subnet\_ids) | The List of the private subnet ID to deploy instance and private lb for vpn relate to VPC | `list(string)` | n/a | yes | -| [public\_lb\_vpn\_domain](#input\_public\_lb\_vpn\_domain) | domain of vpn output will be . | `string` | `"vpn"` | no | -| [public\_rule](#input\_public\_rule) | public rule for run connect vpn |
list(object({
port = number
protocol = string
health_check_port = number
health_check_protocol = string
}))
|
[
{
"health_check_port": 443,
"health_check_protocol": "TCP",
"port": 12383,
"protocol": "UDP"
}
]
| no | -| [public\_subnet\_ids](#input\_public\_subnet\_ids) | The List of the subnet ID to deploy Public Loadbalancer relate to VPC | `list(string)` | n/a | yes | -| [route53\_zone\_name](#input\_route53\_zone\_name) | This is the name of the hosted zone | `string` | `""` | no | -| [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Map of ingress and any specific/overriding attributes to be created | `any` |
{
"allow_to_connect_vpn": {
"cidr_blocks": [
"0.0.0.0/0"
],
"port": "12383",
"protocol": "udp"
}
}
| no | -| [tags](#input\_tags) | Tags to add more; default tags contian {terraform=true, environment=var.environment} | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | The ID of the VPC | `string` | n/a | yes | +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [additional\_sg\_attacment\_ids](#input\_additional\_sg\_attacment\_ids) | (Optional) The ID of the security group. | `list(string)` | `[]` | no | +| [ami](#input\_ami) | (Optional) AMI to use for the instance. Required unless launch\_template is specified and the Launch Template specifes an AMI. If an AMI is specified in the Launch Template, setting ami will override the AMI specified in the Launch Template | `string` | `""` | no | +| [custom\_https\_allow\_cidr](#input\_custom\_https\_allow\_cidr) | cidr block for config pritunl vpn | `list(string)` | `null` | no | +| [efs\_backup\_policy\_enabled](#input\_efs\_backup\_policy\_enabled) | If `true`, it will turn on automatic backups. | `bool` | `true` | no | +| [enable\_ec2\_monitoring](#input\_enable\_ec2\_monitoring) | Enables/disables detailed monitoring | `bool` | `false` | no | +| [enabled\_backup](#input\_enabled\_backup) | Enable Backup EFS | `bool` | `true` | no | +| [environment](#input\_environment) | Environment Variable used as a prefix | `string` | n/a | yes | +| [host\_id](#input\_host\_id) | Override PritunlVPN host id with this option, Use with migration only | `string` | `""` | no | +| [instance\_type](#input\_instance\_type) | (Optional) The instance type to use for the instance. Updates to this field will trigger a stop/start of the EC2 instance. | `string` | `"t2.medium"` | no | +| [is\_create\_private\_lb](#input\_is\_create\_private\_lb) | if true this module will not create private lb for cost optimization | `bool` | `true` | no | +| [is\_create\_route53\_reccord](#input\_is\_create\_route53\_reccord) | if true will create route53 reccord for vpn, vpn console | `bool` | `false` | no | +| [is\_create\_security\_group](#input\_is\_create\_security\_group) | Flag to toggle security group creation | `bool` | `true` | no | +| [is\_enabled\_https\_public](#input\_is\_enabled\_https\_public) | if true will enable https to public loadbalancer else enable to private loadbalancer | `bool` | `true` | no | +| [key\_name](#input\_key\_name) | Key name of the Key Pair to use for the vpn instance; which can be managed using | `string` | `null` | no | +| [prefix](#input\_prefix) | The prefix name of customer to be displayed in AWS console and resource | `string` | n/a | yes | +| [private\_lb\_vpn\_domain](#input\_private\_lb\_vpn\_domain) | domain of vpn console output will be . | `string` | `"vpn-console"` | no | +| [private\_rule](#input\_private\_rule) | private rule for run connect vpn |
list(object({
port = number
protocol = string
health_check_port = number
health_check_protocol = string
}))
| `[]` | no | +| [private\_subnet\_ids](#input\_private\_subnet\_ids) | The List of the private subnet ID to deploy instance and private lb for vpn relate to VPC | `list(string)` | n/a | yes | +| [public\_lb\_vpn\_domain](#input\_public\_lb\_vpn\_domain) | domain of vpn output will be . | `string` | `"vpn"` | no | +| [public\_rule](#input\_public\_rule) | public rule for run connect vpn |
list(object({
port = number
protocol = string
health_check_port = number
health_check_protocol = string
}))
|
[
{
"health_check_port": 443,
"health_check_protocol": "TCP",
"port": 12383,
"protocol": "UDP"
}
]
| no | +| [public\_subnet\_ids](#input\_public\_subnet\_ids) | The List of the subnet ID to deploy Public Loadbalancer relate to VPC | `list(string)` | n/a | yes | +| [route53\_zone\_name](#input\_route53\_zone\_name) | This is the name of the hosted zone | `string` | `""` | no | +| [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Map of ingress and any specific/overriding attributes to be created | `any` |
{
"allow_to_connect_vpn": {
"cidr_blocks": [
"0.0.0.0/0"
],
"port": "12383",
"protocol": "udp"
}
}
| no | +| [tags](#input\_tags) | Tags to add more; default tags contian {terraform=true, environment=var.environment} | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | The ID of the VPC | `string` | n/a | yes | ## Outputs -| Name | Description | -|------------------------------------------------------------------------------------------------|--------------------------------------------------------| -| [efs\_dns\_name](#output\_efs\_dns\_name) | The DNS name for the filesystem | -| [efs\_id](#output\_efs\_id) | The ID that identifies the file system for pritunl vpn | -| [lb\_private\_dns](#output\_lb\_private\_dns) | The DNS name of the private load balancer. | -| [lb\_public\_dns](#output\_lb\_public\_dns) | The DNS name of the public load balancer. | -| [security\_group\_arn](#output\_security\_group\_arn) | ARN of the security group associated to this ec2 | -| [security\_group\_id](#output\_security\_group\_id) | ID of the security group associated to this ec2 | -| [vpn\_private\_dns](#output\_vpn\_private\_dns) | private dns for connect vpn server | -| [vpn\_public\_dns](#output\_vpn\_public\_dns) | public dns for connect vpn server | +| Name | Description | +|------|-------------| +| [efs\_dns\_name](#output\_efs\_dns\_name) | The DNS name for the filesystem | +| [efs\_id](#output\_efs\_id) | The ID that identifies the file system for pritunl vpn | +| [lb\_private\_dns](#output\_lb\_private\_dns) | The DNS name of the private load balancer. | +| [lb\_public\_dns](#output\_lb\_public\_dns) | The DNS name of the public load balancer. | +| [security\_group\_arn](#output\_security\_group\_arn) | ARN of the security group associated to this ec2 | +| [security\_group\_id](#output\_security\_group\_id) | ID of the security group associated to this ec2 | +| [vpn\_private\_dns](#output\_vpn\_private\_dns) | private dns for connect vpn server | +| [vpn\_public\_dns](#output\_vpn\_public\_dns) | public dns for connect vpn server | From 6ed4b7752af84d7d5d1d8a8ae17036dea3d66bd6 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 12:18:28 +0700 Subject: [PATCH 04/23] refact: move to main file --- data.tf | 17 ------------- locals.tf | 28 -------------------- main.tf | 76 +++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 58 deletions(-) delete mode 100644 data.tf delete mode 100644 locals.tf diff --git a/data.tf b/data.tf deleted file mode 100644 index 341517a..0000000 --- a/data.tf +++ /dev/null @@ -1,17 +0,0 @@ -data "aws_ami" "amazon_linux" { - most_recent = true - filter { - name = "name" - values = ["amzn2-ami-kernel-5.10-hvm-*"] - } - - filter { - name = "virtualization-type" - values = ["hvm"] - } - owners = ["137112412989"] # amazon -} - -data "aws_vpc" "this" { - id = var.vpc_id -} diff --git a/locals.tf b/locals.tf deleted file mode 100644 index 25f5557..0000000 --- a/locals.tf +++ /dev/null @@ -1,28 +0,0 @@ -locals { - tags = merge( - { - "Environment" = var.environment, - "Terraform" = "true" - }, - var.tags - ) - name = format("%s-%s-%s", var.prefix, var.environment, "vpn") - profile_policy_arns = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", "arn:aws:iam::aws:policy/AmazonElasticFileSystemClientReadWriteAccess"] - security_group_ids = concat([module.efs.security_group_client_id], var.additional_sg_attacment_ids, var.is_create_security_group ? [aws_security_group.this[0].id] : []) - - console_rule = [{ - port = 443, - protocol = "TCP" - health_check_protocol = "TCP" - }] - public_rule = concat(var.public_rule, var.is_enabled_https_public ? local.console_rule : []) - private_rule = concat(var.private_rule, local.console_rule) - default_https_allow_cidr = var.is_enabled_https_public ? ["0.0.0.0/0"] : [data.aws_vpc.this.cidr_block] - security_group_ingress_rules = merge({ - allow_to_config_vpn = { - port = "443" - cidr_blocks = var.custom_https_allow_cidr != null ? var.custom_https_allow_cidr : local.default_https_allow_cidr - } - }, - var.security_group_ingress_rules) -} diff --git a/main.tf b/main.tf index b023021..592f62c 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,66 @@ +# ############################################################################# +# Additional Data +# ############################################################################# +locals { + tags = merge( + { + "Environment" = var.environment, + "Terraform" = "true" + }, + var.tags + ) + name = format("%s-%s-%s", var.prefix, var.environment, "vpn") + profile_policy_arns = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", "arn:aws:iam::aws:policy/AmazonElasticFileSystemClientReadWriteAccess"] + security_group_ids = concat([module.efs.security_group_client_id], var.additional_sg_attacment_ids, var.is_create_security_group ? [aws_security_group.this[0].id] : []) + + console_rule = [{ + port = 443, + protocol = "TCP" + health_check_protocol = "TCP" + }] + public_rule = concat(var.public_rule, var.is_enabled_https_public ? local.console_rule : []) + private_rule = concat(var.private_rule, local.console_rule) + default_https_allow_cidr = var.is_enabled_https_public ? ["0.0.0.0/0"] : [data.aws_vpc.this.cidr_block] + security_group_ingress_rules = merge({ + allow_to_config_vpn = { + port = "443" + cidr_blocks = var.custom_https_allow_cidr != null ? var.custom_https_allow_cidr : local.default_https_allow_cidr + } + }, + var.security_group_ingress_rules) +} + +resource "random_string" "host_id" { + count = length(var.host_id) > 0 ? 0 : 1 + + numeric = true + lower = true + upper = false + length = 32 + special = false +} + +data "aws_vpc" "this" { + id = var.vpc_id +} + +# ############################################################################# +# AMI +# ############################################################################# +data "aws_ami" "amazon_linux" { + most_recent = true + filter { + name = "name" + values = ["amzn2-ami-kernel-5.10-hvm-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + owners = ["137112412989"] # amazon +} + # ############################################################################# # EFS Storage # ############################################################################# @@ -73,19 +136,6 @@ resource "aws_security_group_rule" "ingress" { source_security_group_id = lookup(each.value, "source_security_group_id", null) } -# ############################################################################# -# Generate Data -# ############################################################################# -resource "random_string" "host_id" { - count = length(var.host_id) > 0 ? 0 : 1 - - numeric = true - lower = true - upper = false - length = 32 - special = false -} - # ############################################################################# # IAM Roles # ############################################################################# From a9354c37b23d726d339bf6fab1ac837763848d46 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 12:21:15 +0700 Subject: [PATCH 05/23] fix: fix drop-in service for mongod --- templates/user_data.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/user_data.sh b/templates/user_data.sh index fd4a1c7..a08d8c4 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -78,6 +78,7 @@ sudo chown -R mongod:mongod /mnt/efs/ echo ">>> Setting up drop-in service for MongoDB" # Auto Restart MongoDB to prevent it faile to start on the first time. +sudo mkdir -p /etc/systemd/system/mongod.d echo "${mongodb_drop_in_service_file}" | sudo tee /etc/systemd/system/mongod.d/10-auto-restart-on-failure.conf sudo systemctl daemon-reload From 5ab6741a8e5ae0c0d751824253b401bf23c3f6cf Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 12:27:45 +0700 Subject: [PATCH 06/23] fix: add drop-in systemd for pritunl --- main.tf | 3 ++- ...-drop-in.conf => systemd-drop-in-on-failure.conf} | 0 templates/user_data.sh | 12 +++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) rename templates/{systemd-mongod-drop-in.conf => systemd-drop-in-on-failure.conf} (100%) diff --git a/main.tf b/main.tf index 592f62c..f53aa9b 100644 --- a/main.tf +++ b/main.tf @@ -222,7 +222,8 @@ module "launch_template" { cloudwatch_agent_config_file = templatefile("${path.module}/templates/cloudwatch-agent-conf.json", { cloudwatch_metric_namespace = "EC2/pritunl-vpn" }), - mongodb_drop_in_service_file = file("${path.module}/templates/systemd-mongod-drop-in.conf"), + mongodb_drop_in_service_file = file("${path.module}/templates/systemd-drop-in-on-failure.conf"), + pritunl_drop_in_service_file = file("${path.module}/templates/systemd-drop-in-on-failure.conf"), pritunl_host_id = length(var.host_id) > 0 ? var.host_id : random_string.host_id[0].result })) iam_instance_profile = { arn : aws_iam_instance_profile.this.arn } diff --git a/templates/systemd-mongod-drop-in.conf b/templates/systemd-drop-in-on-failure.conf similarity index 100% rename from templates/systemd-mongod-drop-in.conf rename to templates/systemd-drop-in-on-failure.conf diff --git a/templates/user_data.sh b/templates/user_data.sh index a08d8c4..783f75d 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -76,20 +76,30 @@ echo ">>> Setting up data volume for MongoDB ..." sudo sed -i.bak "s/\/var\/lib\/mongo/\/mnt\/efs/g" /etc/mongod.conf sudo chown -R mongod:mongod /mnt/efs/ -echo ">>> Setting up drop-in service for MongoDB" +echo ">>> Setting up drop-in service for MongoDB and Pritunl" # Auto Restart MongoDB to prevent it faile to start on the first time. sudo mkdir -p /etc/systemd/system/mongod.d +sudo mkdir -p /etc/systemd/system/pritunl.d echo "${mongodb_drop_in_service_file}" | sudo tee /etc/systemd/system/mongod.d/10-auto-restart-on-failure.conf +echo "${pritunl_drop_in_service_file}" | sudo tee /etc/systemd/system/pritunl.d/10-auto-restart-on-failure.conf sudo systemctl daemon-reload echo ">>> Starting MongoDB service ..." sudo systemctl start mongod pritunl sudo systemctl enable mongod pritunl +# Prevent MongoDB's crashed by db lock +echo ">>> Delaying for MongoDB startup (1m) ..." +sleep 60 + echo ">>> Starting PritunlVPN service ..." sudo systemctl start pritunl sudo systemctl enable pritunl +# Prevent Pritunl Failed to start when MongoDB's failed to start +echo ">>> Delaying for PritunlVPN startup (1m) ..." +sleep 60 + echo ">>> Reconfiguring PritunlVPN ..." sudo pritunl set-host-id "${pritunl_host_id}" sudo pritunl set-mongodb mongodb://localhost:27017/pritunl From 99abcc8d5ae2bd98fc1a637c6f10bd73ca1b8c53 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 13:57:13 +0700 Subject: [PATCH 07/23] test: remove the output redirection --- templates/user_data.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/user_data.sh b/templates/user_data.sh index 783f75d..3b90998 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -1,8 +1,8 @@ #!/bin/bash -xe -# Redirect stdout from user_data to console log -# https://aws.amazon.com/premiumsupport/knowledge-center/ec2-linux-log-user-data/ -exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 +# # Redirect stdout from user_data to console log +# # https://aws.amazon.com/premiumsupport/knowledge-center/ec2-linux-log-user-data/ +# exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 echo "################################################################### # Script Name : amazon-linux-pritunl-install.sh From 0eac39f00aa02fabd2136ff61adc94dc60bbfaf0 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 14:21:57 +0700 Subject: [PATCH 08/23] fix: fix bootstrap script and ami --- main.tf | 6 ++++-- templates/mongodb-repo.list | 6 ++++++ templates/pritunl-repo.list | 5 +++++ templates/user_data.sh | 17 ++--------------- 4 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 templates/mongodb-repo.list create mode 100644 templates/pritunl-repo.list diff --git a/main.tf b/main.tf index f53aa9b..027d071 100644 --- a/main.tf +++ b/main.tf @@ -51,7 +51,7 @@ data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" - values = ["amzn2-ami-kernel-5.10-hvm-*"] + values = ["amzn2-ami-*-hvm-*-x86_64-ebs"] } filter { @@ -218,10 +218,12 @@ module "launch_template" { name = "pritunl-vpn" user_data = base64encode(templatefile("${path.module}/templates/user_data.sh", { - efs_id = module.efs.id, cloudwatch_agent_config_file = templatefile("${path.module}/templates/cloudwatch-agent-conf.json", { cloudwatch_metric_namespace = "EC2/pritunl-vpn" }), + efs_id = module.efs.id, + mongodb_repo_list_file = file("${path.module}/templates/mongodb-repo.list"), + pritunl_repo_list_file = file("${path.module}/templates/pritunl-repo.list"), mongodb_drop_in_service_file = file("${path.module}/templates/systemd-drop-in-on-failure.conf"), pritunl_drop_in_service_file = file("${path.module}/templates/systemd-drop-in-on-failure.conf"), pritunl_host_id = length(var.host_id) > 0 ? var.host_id : random_string.host_id[0].result diff --git a/templates/mongodb-repo.list b/templates/mongodb-repo.list new file mode 100644 index 0000000..d46ceb5 --- /dev/null +++ b/templates/mongodb-repo.list @@ -0,0 +1,6 @@ +[mongodb-org-5.0] +name=MongoDB Repository +baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/ +gpgcheck=1 +enabled=1 +gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc diff --git a/templates/pritunl-repo.list b/templates/pritunl-repo.list new file mode 100644 index 0000000..c106252 --- /dev/null +++ b/templates/pritunl-repo.list @@ -0,0 +1,5 @@ +[pritunl] +name=Pritunl Repository +baseurl=https://repo.pritunl.com/stable/yum/amazonlinux/2/ +gpgcheck=1 +enabled=1 diff --git a/templates/user_data.sh b/templates/user_data.sh index 3b90998..e5845cf 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -47,22 +47,9 @@ echo "${efs_id}:/ /mnt/efs efs _netdev,noresvport,tls,iam 0 0" | sudo tee -a /et sudo mount -a echo ">>> Adding MongoDB Repository to package manager ..." -sudo tee /etc/yum.repos.d/mongodb-org-5.0.repo << EOF -[mongodb-org-5.0] -name=MongoDB Repository -baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/ -gpgcheck=1 -enabled=1 -gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc -EOF +echo '${mongodb_repo_list_file}' | sudo tee /etc/yum.repos.d/mongodb-org-5.0.repo echo ">>> Adding MongoDB Repository to package manager ..." -sudo tee /etc/yum.repos.d/pritunl.repo << EOF -[pritunl] -name=Pritunl Repository -baseurl=https://repo.pritunl.com/stable/yum/amazonlinux/2/ -gpgcheck=1 -enabled=1 -EOF +echo '${pritunl_repo_list_file}' | sudo tee /etc/yum.repos.d/pritunl.repo echo ">>> Adding Keys for package manager ..." sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm From f2c2a7a2c17d089f4be21d2afa633331cc38ada5 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 14:45:48 +0700 Subject: [PATCH 09/23] fix: fix ami for pritunl --- main.tf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 027d071..97c7739 100644 --- a/main.tf +++ b/main.tf @@ -49,16 +49,18 @@ data "aws_vpc" "this" { # ############################################################################# data "aws_ami" "amazon_linux" { most_recent = true + filter { name = "name" - values = ["amzn2-ami-*-hvm-*-x86_64-ebs"] + values = ["amzn2-ami-hvm-*-x86_64-ebs"] } filter { name = "virtualization-type" values = ["hvm"] } - owners = ["137112412989"] # amazon + + owners = ["amazon"] } # ############################################################################# From 0cc38e546b0cf71cd075c97c16cba916d896ca13 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:10:01 +0700 Subject: [PATCH 10/23] fix: install ssm agent --- templates/user_data.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/templates/user_data.sh b/templates/user_data.sh index e5845cf..f2d414a 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -12,6 +12,12 @@ echo "################################################################### # Email : devops@oozou.com ###################################################################" +echo ">>> Installing SSM Agent ..." +sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm +echo ">>> Enabling SSM Agent ..." +sudo systemctl start amazon-ssm-agent +sudo systemctl enable amazon-ssm-agent + echo ">>> Installing CloudWatch Agent ..." sudo yum install -y amazon-cloudwatch-agent echo '${cloudwatch_agent_config_file}' > cloudwatch-agent-config.json From 28860fa70f4c82aac5ca7ad3add260625c7d15aa Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:10:39 +0700 Subject: [PATCH 11/23] fix: change ami to generic filter --- main.tf | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 97c7739..2bf94f1 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,17 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-hvm-*-x86_64-ebs"] + values = ["amzn2-*"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "block-device-mapping.volume-type" + values = ["gp2"] } filter { From aa372fea8913fce654f2b22806579c5c87c45eaf Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:22:50 +0700 Subject: [PATCH 12/23] fix: fix ami and bootstrap script --- main.tf | 4 ++-- templates/user_data.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/main.tf b/main.tf index 2bf94f1..0560cc5 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-*"] + values = ["amzn2-ami-*"] } filter { @@ -61,7 +61,7 @@ data "aws_ami" "amazon_linux" { } filter { - name = "block-device-mapping.volume-type" + name = "root-device-type" values = ["gp2"] } diff --git a/templates/user_data.sh b/templates/user_data.sh index f2d414a..1e62476 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -1,4 +1,4 @@ -#!/bin/bash -xe +#!/bin/bash -x # # Redirect stdout from user_data to console log # # https://aws.amazon.com/premiumsupport/knowledge-center/ec2-linux-log-user-data/ @@ -20,12 +20,12 @@ sudo systemctl enable amazon-ssm-agent echo ">>> Installing CloudWatch Agent ..." sudo yum install -y amazon-cloudwatch-agent -echo '${cloudwatch_agent_config_file}' > cloudwatch-agent-config.json +echo '${cloudwatch_agent_config_file}' | sudo tee /tmp/cloudwatch-agent-config.json echo ">>> Reconfiguring CloudWatch Agent ..." sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ -a fetch-config \ -m ec2 \ --c file:cw-agent-config.json -s +-c file://tmp/cw-agent-config.json -s echo ">>> Restarting amazon-cloudwatch-agent service..." sudo systemctl restart amazon-cloudwatch-agent sudo systemctl enable amazon-cloudwatch-agent From 2072a44ecb2544779c8bfe997fc8735a4e31bc09 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:26:17 +0700 Subject: [PATCH 13/23] fix: fix ami for pritunl --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 0560cc5..af4a2ed 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-*"] + values = ["amzn2-ami-hvm-*-x86_64-gp2"] } filter { From f7c69ac25f7c1929bea1ebe840ad100244e8c169 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:29:58 +0700 Subject: [PATCH 14/23] fix: fix ami for pritunl --- main.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index af4a2ed..7008847 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-hvm-*-x86_64-gp2"] + values = ["amzn2-ami-*-gp2"] } filter { @@ -62,6 +62,11 @@ data "aws_ami" "amazon_linux" { filter { name = "root-device-type" + values = ["ebs"] + } + + filter { + name = "block-device-mapping.volume-type" values = ["gp2"] } From 13d4fbc3dfe48e07f89759dfbf29e0518422dd2d Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 15:34:29 +0700 Subject: [PATCH 15/23] fix: fix ami for pritunl --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 7008847..64a96ef 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-*-gp2"] + values = ["amzn2-ami-hvm-*-x86_64-gp2"] } filter { From 593636b9bbe83937104610e499dd7473a2fef543 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 16:02:39 +0700 Subject: [PATCH 16/23] fix: change ami to amzn2 kernel 5.10 --- main.tf | 14 +++++++------- templates/user_data.sh | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/main.tf b/main.tf index 64a96ef..d2d5e03 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-hvm-*-x86_64-gp2"] + values = ["amzn2-ami-kernel-5.10-hvm-*"] } filter { @@ -60,11 +60,6 @@ data "aws_ami" "amazon_linux" { values = ["x86_64"] } - filter { - name = "root-device-type" - values = ["ebs"] - } - filter { name = "block-device-mapping.volume-type" values = ["gp2"] @@ -75,7 +70,12 @@ data "aws_ami" "amazon_linux" { values = ["hvm"] } - owners = ["amazon"] + filter { + name = "owner-alias" + values = ["amazon"] + } + + owners = [137112412989] # amazon account id } # ############################################################################# diff --git a/templates/user_data.sh b/templates/user_data.sh index 1e62476..f9a32cc 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -1,4 +1,4 @@ -#!/bin/bash -x +#!/bin/bash -xe # # Redirect stdout from user_data to console log # # https://aws.amazon.com/premiumsupport/knowledge-center/ec2-linux-log-user-data/ From 880ee76afa5ddaf5da5ea6480ff56e86421be040 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 16:05:40 +0700 Subject: [PATCH 17/23] fix: fix ami for pritunl to use generic amzn2 --- main.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index d2d5e03..4eed64f 100644 --- a/main.tf +++ b/main.tf @@ -52,7 +52,7 @@ data "aws_ami" "amazon_linux" { filter { name = "name" - values = ["amzn2-ami-kernel-5.10-hvm-*"] + values = ["amzn2-ami-hvm-*-x86_64-gp2"] } filter { @@ -60,6 +60,11 @@ data "aws_ami" "amazon_linux" { values = ["x86_64"] } + filter { + name = "root-device-type" + values = ["ebs"] + } + filter { name = "block-device-mapping.volume-type" values = ["gp2"] From b524e4fea93bcc336df24b657d90a7c19a7a4a6d Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 16:27:35 +0700 Subject: [PATCH 18/23] fix: fix script to start ssm agent --- templates/user_data.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/user_data.sh b/templates/user_data.sh index f9a32cc..f961d1e 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -16,7 +16,6 @@ echo ">>> Installing SSM Agent ..." sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm echo ">>> Enabling SSM Agent ..." sudo systemctl start amazon-ssm-agent -sudo systemctl enable amazon-ssm-agent echo ">>> Installing CloudWatch Agent ..." sudo yum install -y amazon-cloudwatch-agent From 5ce92dce41beb1a7d0d0984841ab966393997b92 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 16:38:33 +0700 Subject: [PATCH 19/23] fix: fix cloudwatch agent installation --- templates/user_data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/user_data.sh b/templates/user_data.sh index f961d1e..01924d6 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -24,7 +24,7 @@ echo ">>> Reconfiguring CloudWatch Agent ..." sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ -a fetch-config \ -m ec2 \ --c file://tmp/cw-agent-config.json -s +-c file:///tmp/cloudwatch-agent-config.json -s echo ">>> Restarting amazon-cloudwatch-agent service..." sudo systemctl restart amazon-cloudwatch-agent sudo systemctl enable amazon-cloudwatch-agent From fbea5fc4ebcce88c10ae779abafa94961558ce4e Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 16:58:46 +0700 Subject: [PATCH 20/23] fix: fix mongodb package --- templates/user_data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/user_data.sh b/templates/user_data.sh index 01924d6..1cd76bc 100644 --- a/templates/user_data.sh +++ b/templates/user_data.sh @@ -62,7 +62,7 @@ gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 7568D9BB55FF9E5287D586017 gpg --armor --export 7568D9BB55FF9E5287D586017AE645C0CF8E292A > key.tmp; sudo rpm --import key.tmp; rm -f key.tmp echo ">>> Installing PritunlVPN and MongoDB ..." -sudo yum -y install pritunl mongodb-org-5.0.9-1.amzn2 +sudo yum -y install pritunl mongodb-org echo ">>> Setting up data volume for MongoDB ..." sudo sed -i.bak "s/\/var\/lib\/mongo/\/mnt\/efs/g" /etc/mongod.conf From 00076fb6ea862bc74907ddcf3963b84bbd837393 Mon Sep 17 00:00:00 2001 From: be99inner Date: Fri, 18 Nov 2022 17:06:31 +0700 Subject: [PATCH 21/23] chore: update comment for host id --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 90139fb..e957373 100644 --- a/variables.tf +++ b/variables.tf @@ -161,7 +161,7 @@ variable "is_create_private_lb" { } variable "host_id" { - description = "Override PritunlVPN host id with this option, Use with migration only" + description = "Override PritunlVPN host id with this option, Use with migration only (https://docs.pritunl.com/docs/backup)" type = string default = "" } From 9d8eada973caba20dce3a72cb8cca18501b574e4 Mon Sep 17 00:00:00 2001 From: sedthawut tipkanpirome <40098197+xshot9011@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:42:56 +0700 Subject: [PATCH 22/23] (update): efs version to v1.0.5 --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 4eed64f..07a0da1 100644 --- a/main.tf +++ b/main.tf @@ -88,7 +88,7 @@ data "aws_ami" "amazon_linux" { # ############################################################################# module "efs" { source = "oozou/efs/aws" - version = "1.0.4" + version = "1.0.5" prefix = var.prefix environment = var.environment From 3e4439b9eed0f9e58f6e48cf98947ebc60b299a1 Mon Sep 17 00:00:00 2001 From: sedthawut tipkanpirome <40098197+xshot9011@users.noreply.github.com> Date: Wed, 21 Dec 2022 12:29:01 +0700 Subject: [PATCH 23/23] (update): efs policy --- main.tf | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 07a0da1..739828c 100644 --- a/main.tf +++ b/main.tf @@ -86,6 +86,46 @@ data "aws_ami" "amazon_linux" { # ############################################################################# # EFS Storage # ############################################################################# +data "aws_iam_policy_document" "allow_access_efs_policy" { + statement { + actions = [ + "elasticfilesystem:ClientRootAccess", + "elasticfilesystem:ClientWrite" + ] + principals { + type = "AWS" + identifiers = ["*"] + } + resources = ["*"] + condition { + test = "Bool" + variable = "elasticfilesystem:AccessedViaMountTarget" + + values = [ + "true" + ] + } + } + + statement { + effect = "Deny" + actions = ["*"] + principals { + type = "AWS" + identifiers = ["*"] + } + resources = ["*"] + condition { + test = "Bool" + variable = "aws:SecureTransport" + + values = [ + "false" + ] + } + } +} + module "efs" { source = "oozou/efs/aws" version = "1.0.5" @@ -113,7 +153,7 @@ module "efs" { vpc_id = var.vpc_id subnets = var.private_subnet_ids - additional_efs_resource_policies = [] + additional_efs_resource_policies = [data.aws_iam_policy_document.allow_access_efs_policy.json] tags = var.tags }