Skip to content

Instantly share code, notes, and snippets.

@kusw3
Created April 22, 2020 14:25
Show Gist options
  • Save kusw3/ee1a61727b7fce9dabcb64a7412acd0a to your computer and use it in GitHub Desktop.
Save kusw3/ee1a61727b7fce9dabcb64a7412acd0a to your computer and use it in GitHub Desktop.
Sandbox EC2 instance on existing private subnet
data "aws_vpc" "sandbox" {
tags = {
Name = "SandboxVPC"
}
}
data "aws_subnet_ids" "private" {
vpc_id = data.aws_vpc.sandbox.id
filter {
name = "tag:Name"
values = [ "*Private*" ]
}
}
data "aws_subnet_ids" "public" {
vpc_id = data.aws_vpc.sandbox.id
filter {
name = "tag:Name"
values = [ "*Public*" ]
}
}
resource "aws_security_group" "aws-endpoints" {
name = "aws-endpoints-sg"
description = "Allow access to HTTPS in endpoint"
vpc_id = data.aws_vpc.sandbox.id
ingress {
description = "Allow HTTP"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [ data.aws_vpc.sandbox.cidr_block ]
}
lifecycle {
create_before_destroy = true
}
}
# API Gateway Endpoint
resource "aws_vpc_endpoint" "external-api" {
vpc_id = data.aws_vpc.sandbox.id
service_name = "com.amazonaws.eu-central-1.execute-api"
vpc_endpoint_type = "Interface"
security_group_ids = [
aws_security_group.aws-endpoints.id
]
private_dns_enabled = true
}
resource "aws_vpc_endpoint_subnet_association" "eapi-sn" {
for_each = data.aws_subnet_ids.private.ids
vpc_endpoint_id = aws_vpc_endpoint.external-api.id
subnet_id = each.value
}
# SSM endpoint
resource "aws_vpc_endpoint" "ssm" {
vpc_id = data.aws_vpc.sandbox.id
service_name = "com.amazonaws.eu-central-1.ssm"
vpc_endpoint_type = "Interface"
security_group_ids = [
aws_security_group.aws-endpoints.id
]
private_dns_enabled = true
}
resource "aws_vpc_endpoint_subnet_association" "ssm-sn" {
for_each = data.aws_subnet_ids.private.ids
vpc_endpoint_id = aws_vpc_endpoint.ssm.id
subnet_id = each.value
}
# SSM Messages endpoint
resource "aws_vpc_endpoint" "ssmmessages" {
vpc_id = data.aws_vpc.sandbox.id
service_name = "com.amazonaws.eu-central-1.ssmmessages"
vpc_endpoint_type = "Interface"
security_group_ids = [
aws_security_group.aws-endpoints.id
]
private_dns_enabled = true
}
resource "aws_vpc_endpoint_subnet_association" "ssmmessages-sn" {
for_each = data.aws_subnet_ids.private.ids
vpc_endpoint_id = aws_vpc_endpoint.ssmmessages.id
subnet_id = each.value
}
# EC2 Messages Endpoint
resource "aws_vpc_endpoint" "ec2messages" {
vpc_id = data.aws_vpc.sandbox.id
service_name = "com.amazonaws.eu-central-1.ec2messages"
vpc_endpoint_type = "Interface"
security_group_ids = [
aws_security_group.aws-endpoints.id
]
private_dns_enabled = true
}
resource "aws_vpc_endpoint_subnet_association" "ec2messages-sn" {
for_each = data.aws_subnet_ids.private.ids
vpc_endpoint_id = aws_vpc_endpoint.ec2messages.id
subnet_id = each.value
}
# Load teamplate for provision script of bastion host
data "template_file" "user_data" {
template = file("./helpers/provision.sh")
vars = {
TF_tz = "Europe/Andorra"
TF_host_fqdn = "ec2-sandbox.kusw3.com"
}
}
# Picking latest ami available for amazon linux 2
data "aws_ami" "al2" {
most_recent = true
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
owners = ["amazon"]
}
resource "aws_instance" "bastion" {
ami = data.aws_ami.al2.id
instance_type = "t2.micro"
iam_instance_profile = aws_iam_instance_profile.ssm_profile.name
subnet_id = element(tolist(data.aws_subnet_ids.private.ids), 1)
user_data = data.template_file.user_data.rendered
tags = {
Name = "SandBoxTest"
}
}
resource "aws_iam_instance_profile" "ssm_profile" {
name = "ssm_profile"
role = aws_iam_role.ssm.name
}
resource "aws_iam_role" "ssm" {
name = "ssm_role"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "ssm-attach" {
role = aws_iam_role.ssm.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
#!/bin/bash
# Helper script to provision a SSM accessible bastion host
# Tested on amzlinux2 OS
# marc@kusw3.com
setup() {
# Setting up timezone
timedatectl set-timezone ${TF_tz}
hostnamectl set-hostname ${TF_host_fqdn}
hostn=$(echo ${TF_host_fqdn} | cut -d. -f1)
sed -i "s/127.0.0.1/127.0.0.1 ${TF_host_fqdn} $hostn/" /etc/hosts
echo 'preserve_hostname: true' > /etc/cloud/cloud.cfg.d/99_preserve_name.cfg
}
install_ncat() {
sudo yum install nmap-ncat -y
}
setup
for cmd in ncat;
do
if [[ -z "$(which $cmd)" ]]; then
echo -n "Installing $cmd ... "
if $(install_$cmd); then
echo " DONE."
else
echo "Error installing $cmd. See above."
fi
fi
done
echo "## Finished setup"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment