From fd28c682e8741f08918bb81b81a9a56a58bfa752 Mon Sep 17 00:00:00 2001 From: Daniel Hill Date: Fri, 26 Feb 2021 18:48:32 +0000 Subject: [PATCH] add option for setting proxy and no_proxy (#16) * add option for setting proxy and no_proxy Signed-off-by: Daniel.Hill * add example where proxy is set --- examples/hybrid_http_proxy/README.md | 24 +++ examples/hybrid_http_proxy/iam.tf | 44 +++++ examples/hybrid_http_proxy/main.tf | 173 ++++++++++++++++++ examples/hybrid_http_proxy/ssm.tf | 92 ++++++++++ .../templates/cloud-init.cfg | 23 +++ .../hybrid_http_proxy/templates/cloud-init.sh | 29 +++ .../terraform.tfvars.example | 10 + examples/hybrid_http_proxy/variables.tf | 94 ++++++++++ main.tf | 1 + templates/cloud-init.sh | 6 + variables.tf | 14 ++ 11 files changed, 510 insertions(+) create mode 100644 examples/hybrid_http_proxy/README.md create mode 100644 examples/hybrid_http_proxy/iam.tf create mode 100644 examples/hybrid_http_proxy/main.tf create mode 100644 examples/hybrid_http_proxy/ssm.tf create mode 100644 examples/hybrid_http_proxy/templates/cloud-init.cfg create mode 100644 examples/hybrid_http_proxy/templates/cloud-init.sh create mode 100644 examples/hybrid_http_proxy/terraform.tfvars.example create mode 100644 examples/hybrid_http_proxy/variables.tf diff --git a/examples/hybrid_http_proxy/README.md b/examples/hybrid_http_proxy/README.md new file mode 100644 index 0000000..f2653f9 --- /dev/null +++ b/examples/hybrid_http_proxy/README.md @@ -0,0 +1,24 @@ +# Hybrid Example With External Database + +## Status + +TODO: + +## Description + +This code will act as an example of how to call the terraform-aws-kong-gw module. +It should highlight the required inputs to get the module to deploy kong in hybrid +mode when a database is being provided from outside of the module. + +## Run + +``` bash +terraform init +terraform apply +``` + +## Destroy + +``` bash +terraform destroy +``` diff --git a/examples/hybrid_http_proxy/iam.tf b/examples/hybrid_http_proxy/iam.tf new file mode 100644 index 0000000..038add7 --- /dev/null +++ b/examples/hybrid_http_proxy/iam.tf @@ -0,0 +1,44 @@ +data "aws_iam_policy_document" "kong-ssm" { + statement { + actions = ["ssm:DescribeParameters"] + resources = ["*"] + } + + statement { + actions = ["ssm:GetParameter"] + resources = ["arn:aws:ssm:*:*:parameter/${var.service}/${var.environment}/*"] + } + + statement { + actions = ["kms:Decrypt"] + resources = [aws_kms_alias.kong.target_key_arn] + } +} + +resource "aws_iam_role_policy" "kong-ssm" { + name = format("%s-%s-ssm", var.service, var.environment) + role = aws_iam_role.kong.id + + policy = data.aws_iam_policy_document.kong-ssm.json +} + +data "aws_iam_policy_document" "kong" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "kong" { + name = format("%s-%s", var.service, var.environment) + assume_role_policy = data.aws_iam_policy_document.kong.json +} + +resource "aws_iam_instance_profile" "kong" { + name = format("%s-%s", var.service, var.environment) + role = aws_iam_role.kong.id +} diff --git a/examples/hybrid_http_proxy/main.tf b/examples/hybrid_http_proxy/main.tf new file mode 100644 index 0000000..1c4eee5 --- /dev/null +++ b/examples/hybrid_http_proxy/main.tf @@ -0,0 +1,173 @@ +provider "aws" { + region = var.region +} + +data "aws_ami" "ubuntu" { + most_recent = true + owners = ["099720109477"] + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } +} + +resource "aws_vpc" "vpc" { + cidr_block = var.vpc_cidr_block + enable_dns_hostnames = true + enable_dns_support = true +} + +resource "aws_internet_gateway" "ig" { + vpc_id = aws_vpc.vpc.id +} + +resource "aws_eip" "nat_eip" { + vpc = true + depends_on = [aws_internet_gateway.ig] +} + +resource "aws_subnet" "public_subnet" { + vpc_id = aws_vpc.vpc.id + cidr_block = "10.0.5.0/24" + availability_zone = "${var.region}c" + map_public_ip_on_launch = true +} + +resource "aws_security_group" "allow_postgres" { + name = "allow_postgres" + description = "Allow postgres inbound traffic" + vpc_id = aws_vpc.vpc.id + + ingress { + description = "postgresql from VPC" + from_port = 5432 + to_port = 5432 + protocol = "TCP" + cidr_blocks = [aws_vpc.vpc.cidr_block] + } + + ingress { + description = "postgresql from VPC" + from_port = 22 + to_port = 22 + protocol = "TCP" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = var.tags +} + +resource "aws_nat_gateway" "nat" { + allocation_id = aws_eip.nat_eip.id + subnet_id = aws_subnet.public_subnet.id + depends_on = [aws_internet_gateway.ig] +} + +resource "aws_route_table" "public" { + vpc_id = aws_vpc.vpc.id +} + +resource "aws_route" "public_internet_gateway" { + route_table_id = aws_route_table.public.id + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.ig.id +} + +resource "aws_route_table_association" "public" { + subnet_id = aws_subnet.public_subnet.id + route_table_id = aws_route_table.public.id +} + +locals { + user_data = templatefile("${path.module}/templates/cloud-init.cfg", {}) + user_data_script = templatefile("${path.module}/templates/cloud-init.sh", { + db_master_pass = random_string.master_password.result + db_master_user = var.postgres_master_user + }) +} + +data "template_cloudinit_config" "cloud-init" { + gzip = true + base64_encode = true + + part { + filename = "init.cfg" + content_type = "text/cloud-config" + content = local.user_data + } + + part { + content_type = "text/x-shellscript" + content = local.user_data_script + } +} + +resource "aws_instance" "external_postgres" { + ami = data.aws_ami.ubuntu.id + instance_type = "t3.medium" + key_name = var.key_name + subnet_id = aws_subnet.public_subnet.id + vpc_security_group_ids = [aws_security_group.allow_postgres.id] + user_data = data.template_cloudinit_config.cloud-init.rendered + tags = var.tags +} + +module "create_kong_asg" { + source = "../../" + vpc_id = aws_vpc.vpc.id + ami_id = data.aws_ami.ubuntu.id + key_name = var.key_name + region = var.region + vpc_cidr_block = aws_vpc.vpc.cidr_block + environment = var.environment + service = var.service + description = var.description + iam_instance_profile_name = aws_iam_instance_profile.kong.name + asg_desired_capacity = var.asg_desired_capacity + proxy_config = var.proxy_config + + postgres_config = { + master_user = var.postgres_master_user + master_password = random_string.master_password.result + } + + postgres_host = aws_instance.external_postgres.private_ip + + kong_database_config = { + user = var.kong_database_user + name = var.kong_database_name + password = var.kong_database_password + } + + skip_rds_creation = true + tags = var.tags +} + +resource "aws_route_table" "private" { + vpc_id = aws_vpc.vpc.id +} + +resource "aws_route" "private_nat_gateway" { + route_table_id = aws_route_table.private.id + destination_cidr_block = "0.0.0.0/0" + nat_gateway_id = aws_nat_gateway.nat.id +} + +resource "aws_route_table_association" "private" { + count = length(module.create_kong_asg.private_subnet_ids) + subnet_id = element(module.create_kong_asg.private_subnet_ids, count.index) + route_table_id = aws_route_table.private.id +} diff --git a/examples/hybrid_http_proxy/ssm.tf b/examples/hybrid_http_proxy/ssm.tf new file mode 100644 index 0000000..95bbf94 --- /dev/null +++ b/examples/hybrid_http_proxy/ssm.tf @@ -0,0 +1,92 @@ +resource "aws_kms_key" "kong" { + description = format("%s-%s", var.service, var.environment) + + tags = merge( + { + "Name" = format("%s-%s", var.service, var.environment), + "Environment" = var.environment, + "Description" = var.description, + "Service" = var.service, + }, + var.tags + ) +} + +resource "aws_kms_alias" "kong" { + name = format("alias/%s-%s", var.service, var.environment) + target_key_id = aws_kms_key.kong.key_id +} + +resource "aws_ssm_parameter" "ee-bintray-auth" { + name = format("/%s/%s/ee/bintray-auth", var.service, var.environment) + type = "SecureString" + value = var.ee_bintray_auth + + key_id = aws_kms_alias.kong.target_key_arn + + lifecycle { + ignore_changes = [value] + } +} + +resource "aws_ssm_parameter" "ee-license" { + name = format("/%s/%s/ee/license", var.service, var.environment) + type = "SecureString" + value = var.ee_license + + key_id = aws_kms_alias.kong.target_key_arn + + lifecycle { + ignore_changes = [value] + } +} + +resource "random_string" "admin_token" { + length = 32 + special = false +} + +resource "aws_ssm_parameter" "ee-admin-token" { + name = format("/%s/%s/ee/admin/token", var.service, var.environment) + type = "SecureString" + value = random_string.admin_token.result + + key_id = aws_kms_alias.kong.target_key_arn + + lifecycle { + ignore_changes = [value] + } +} + +resource "aws_ssm_parameter" "db-password" { + name = format("/%s/%s/db/password", var.service, var.environment) + type = "SecureString" + value = var.kong_database_password + + key_id = aws_kms_alias.kong.target_key_arn + + lifecycle { + ignore_changes = [value] + } + + overwrite = true +} + +resource "random_string" "master_password" { + length = 32 + special = false +} + +resource "aws_ssm_parameter" "db-master-password" { + name = format("/%s/%s/db/password/master", var.service, var.environment) + type = "SecureString" + value = random_string.master_password.result + + key_id = aws_kms_alias.kong.target_key_arn + + lifecycle { + ignore_changes = [value] + } + + overwrite = true +} diff --git a/examples/hybrid_http_proxy/templates/cloud-init.cfg b/examples/hybrid_http_proxy/templates/cloud-init.cfg new file mode 100644 index 0000000..4054fa1 --- /dev/null +++ b/examples/hybrid_http_proxy/templates/cloud-init.cfg @@ -0,0 +1,23 @@ +#cloud-config + +users: + - default + +write_files: + - path: /etc/apt/apt.conf.d/00InstallRecommends + owner: root:root + permissions: '0644' + content: | + APT::Install-Recommends "false"; + +# Package configuration +apt: + primary: + - arches: [default] + +apt_update: true +package_upgrade: true +packages: + - apt-listchanges + - unattended-upgrades + - dnsutils diff --git a/examples/hybrid_http_proxy/templates/cloud-init.sh b/examples/hybrid_http_proxy/templates/cloud-init.sh new file mode 100644 index 0000000..f7eb4ed --- /dev/null +++ b/examples/hybrid_http_proxy/templates/cloud-init.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -x +exec &> /tmp/cloud-init.log + +apt-get update + +apt-get install -y apt-transport-https \ + ca-certificates curl gnupg-agent \ + software-properties-common + +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - + +add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + +apt-get update +apt-get install -y docker-ce docker-ce-cli containerd.io + +mkdir -p /root/data + +sleep 10 + +docker run -d \ + --env POSTGRES_PASSWORD=${db_master_pass} \ + --env POSTGRES_USER=${db_master_user} -v /root/data:/var/lib/postgresql/data \ + -p 5432:5432 \ + postgres:13.1 diff --git a/examples/hybrid_http_proxy/terraform.tfvars.example b/examples/hybrid_http_proxy/terraform.tfvars.example new file mode 100644 index 0000000..166ba11 --- /dev/null +++ b/examples/hybrid_http_proxy/terraform.tfvars.example @@ -0,0 +1,10 @@ +region = "" # an aws region +key_name = "" # does not need to be set +vpc_cidr_block = "" # cidr range for the vpc +kong_database_password = "" + +proxy_config = { + http_proxy = "" # e.g. "http://proxy.example.com:1234" + https_proxy = "" # e.g. "https://proxy.example.com:1234" + no_proxy = "169.254.169.254,127.0.0.1" +} diff --git a/examples/hybrid_http_proxy/variables.tf b/examples/hybrid_http_proxy/variables.tf new file mode 100644 index 0000000..2d8989d --- /dev/null +++ b/examples/hybrid_http_proxy/variables.tf @@ -0,0 +1,94 @@ +variable "region" { + description = "The name of an AWS region" + type = string +} + +variable "key_name" { + description = "The name of an AWS ssh key pari to associate with the instances in the ASG" + type = string + default = null +} + +variable "kong_database_password" { + description = "The password to use for the kong database" + type = string +} + +variable "environment" { + description = "Resource environment tag (i.e. dev, stage, prod)" + type = string + default = "test" +} + +variable "service" { + description = "Resource service tag" + type = string + default = "kong" +} + +variable "description" { + description = "Resource description tag" + type = string + default = "Kong API Gateway" +} + +variable "ee_bintray_auth" { + description = "enterprise repo creds" + type = string + default = "placeholder" +} + +variable "ee_license" { + description = "kong enterprise license" + type = string + default = "placeholder" +} + +variable "vpc_cidr_block" { + description = "VPC cidr range" + type = string +} + +variable "asg_desired_capacity" { + description = "The size of the autoscaling group" + type = string + default = 2 +} + +variable "postgres_master_user" { + description = "The master user for postgresql" + type = string + default = "root" +} + +variable "kong_database_name" { + description = "The kong database name" + type = string + default = "kong" +} + +variable "kong_database_user" { + description = "The database use needed to access kong" + type = string + default = "kong" +} + +variable "tags" { + default = { + "Dept" = "Testing", + } +} + +variable "proxy_config" { + description = "(optional) Configure HTTP, HTTPS, and NO_PROXY" + type = object({ + http_proxy = string + https_proxy = string + no_proxy = string + }) + default = { + http_proxy = null + https_proxy = null + no_proxy = null + } +} diff --git a/main.tf b/main.tf index a873892..5abee6c 100644 --- a/main.tf +++ b/main.tf @@ -27,6 +27,7 @@ locals { user_data = templatefile("${path.module}/templates/cloud-init.cfg", {}) user_data_script = templatefile("${path.module}/templates/cloud-init.sh", { + PROXY_CONFIG = var.proxy_config DB_USER = var.kong_database_config.user DB_HOST = local.db_info.endpoint DB_NAME = local.db_info.database_name diff --git a/templates/cloud-init.sh b/templates/cloud-init.sh index c00dc70..4c87ffd 100644 --- a/templates/cloud-init.sh +++ b/templates/cloud-init.sh @@ -3,6 +3,12 @@ set -x exec &> /tmp/cloud-init.log +%{ for config_key, config_value in PROXY_CONFIG ~} +%{ if config_value != null ~} +export ${config_key}="${config_value}" +%{ endif ~} +%{ endfor ~} + # Pause: in testing we need this # to make sure we wait to be routed out # the internet before trying to get diff --git a/variables.tf b/variables.tf index d349138..0058903 100644 --- a/variables.tf +++ b/variables.tf @@ -371,3 +371,17 @@ variable "tags" { description = "Tags to apply to aws resources" type = map(string) } + +variable "proxy_config" { + description = "(optional) Configure HTTP, HTTPS, and NO_PROXY" + type = object({ + http_proxy = string + https_proxy = string + no_proxy = string + }) + default = { + http_proxy = null + https_proxy = null + no_proxy = null + } +}