Create infra

This commit is contained in:
Daniel Mason 2023-04-22 13:17:41 +12:00
parent 1bb150d44e
commit 2d32a3c4bb
Signed by: idanoo
GPG key ID: 387387CDBC02F132
9 changed files with 278 additions and 34 deletions

2
.gitignore vendored
View file

@ -37,4 +37,6 @@ override.tf.json
.terraformrc
terraform.rc
.terraform.lock.hcl
.terraform
# End of https://www.toptal.com/developers/gitignore/api/terraform

View file

@ -1,3 +1,3 @@
# Automate Terraform with GitHub Actions
# FediServices.nz AWS Infra
This repo is a companion repo to the [Automate Terraform with GitHub Actions tutorial](https://developer.hashicorp.com/terraform/tutorials/automation/github-actions).
This repo contains the code required to deploy status.fediservices.nz onto an EC2 instance with an EIP.

55
ec2.tf
View file

@ -1,35 +1,26 @@
# # Instance
# resource "aws_instance" "instance" {
# ami = data.aws_ami.ubuntu.id
# instance_type = "t4g.micro"
# iam_instance_profile = aws_iam_instance_profile.profile.name
# availability_zone = element(aws_subnet.subnet.*.availability_zone, 1)
# user_data = data.template_file.userdata.rendered
# subnet_id = element(aws_subnet.subnet.*.id, 1)
# key_name = var.ssh_key
# vpc_security_group_ids = [aws_security_group.sg.id]
# }
# Instance
resource "aws_instance" "instance" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
iam_instance_profile = aws_iam_instance_profile.profile.name
availability_zone = element(aws_subnet.subnet.*.availability_zone, 1)
user_data = data.template_file.userdata.rendered
subnet_id = element(aws_subnet.subnet.*.id, 1)
key_name = var.ssh_key
vpc_security_group_ids = [aws_security_group.sg.id]
}
# # Elastic IP
# resource "aws_eip" "eip" {
# instance = aws_instance.instance.id
# vpc = true
# Elastic IP
resource "aws_eip" "eip" {
instance = aws_instance.instance.id
vpc = true
}
# tags = var.tags
# }
# # Create a new load balancer attachment
# resource "aws_elb_attachment" "attachment" {
# elb = aws_elb.lb.id
# instance = aws_instance.instance.id
# }
# # EBS Vol for persistance
# resource "aws_ebs_volume" "instance" {
# availability_zone = element(aws_subnet.subnet.*.availability_zone, 1)
# size = "8"
# type = "gp2"
# encrypted = true
# }
# EBS Vol for persistance
resource "aws_ebs_volume" "ebs" {
availability_zone = element(aws_subnet.subnet.*.availability_zone, 1)
size = "1"
type = "gp3"
encrypted = true
}

93
iam.tf Normal file
View file

@ -0,0 +1,93 @@
resource "aws_iam_role" "role" {
name = "status"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_instance_profile" "profile" {
name = "status"
role = aws_iam_role.role.name
}
resource "aws_iam_role_policy" "policy" {
name = aws_iam_role.role.name
role = aws_iam_role.role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:CreateTags",
"ec2:DetachVolume",
"ec2:DescribeVolumes",
"ec2:DescribeInstances",
"ec2:TerminateInstances"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:DescribeAssociation",
"ssm:GetDeployablePatchSnapshotForInstance",
"ssm:GetDocument",
"ssm:DescribeDocument",
"ssm:GetManifest",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:ListAssociations",
"ssm:ListInstanceAssociations",
"ssm:PutInventory",
"ssm:PutComplianceItems",
"ssm:PutConfigurePackageResult",
"ssm:UpdateAssociationStatus",
"ssm:UpdateInstanceAssociationStatus",
"ssm:UpdateInstanceInformation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
EOF
}

40
sg.tf Normal file
View file

@ -0,0 +1,40 @@
# Security groups to access database1.apse2
resource "aws_security_group" "sg" {
name = "status.fediservices.nz"
description = "status.fediservices.nz"
vpc_id = aws_vpc.vpc.id
}
# Allow out
resource "aws_security_group_rule" "allow_egress" {
security_group_id = aws_security_group.sg.id
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
# Allow HTTP traffic
resource "aws_security_group_rule" "http" {
security_group_id = aws_security_group.sg.id
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
# Allow HTTPS traffic
resource "aws_security_group_rule" "https" {
security_group_id = aws_security_group.sg.id
type = "ingress"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}

9
template.tf Normal file
View file

@ -0,0 +1,9 @@
# Userdata
data "template_file" "userdata" {
template = file("${path.module}/templates/userdata.tpl")
vars = {
data_root = "/data"
volume = aws_ebs_volume.ebs.id
}
}

View file

@ -1,2 +1,61 @@
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive
# Install Packages / Update
sudo apt update -q
sudo apt install -qy jq unzip htop net-tools
sudo apt -y upgrade
# Install awscli
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Install Docker
curl -sSL https://get.docker.com/ | sh
# Get / cache instance meta data
sudo wget -N -i http://169.254.169.254/latest/meta-data/ -P /etc/amazon-ec2
METADATA=$(curl http://169.254.169.254/latest/dynamic/instance-identity/document)
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ACC_ID=$(echo $METADATA | jq -r .accountId)
# Set vars
device="xvdf"
volume="${volume}"
# Detect if volume is attached
while [[ ! $(/bin/lsblk) == *$device* ]]; do
# Detect if we are on a Nitro based VM and then lookup nvme device
if [ -f /sys/devices/virtual/dmi/id/board_asset_tag ]; then
sudo apt install -qy nvme-cli
for line in $(/bin/lsblk | awk '{print $1}' | /bin/grep ^nvme);
do
if [[ $(sudo /usr/sbin/nvme id-ctrl -v /dev/$line | grep $${volume/-/} | wc -c) -ne 0 ]]; then
device=$line
fi
done
fi
done;
# Mount data folder and bootstrap
sudo mkdir ${data_root}
if [[ $(blkid /dev/$device | head -c1 | wc -c) -eq 0 ]]; then
sudo mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/$device
fi
# Auto expand FS before mount
sudo mount -t ext4 -o noatime,data=writeback,barrier=0,nobh,errors=remount-ro /dev/$device ${data_root}
sudo resize2fs /dev/$device
sudo chown ubuntu:ubuntu -R ${data_root}
# Run it!
docker run -d \
--restart=always \
-p 3001:3001 \
-v ${data_root}/uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma
sudo snap start amazon-ssm-agent

12
variables.tf Normal file
View file

@ -0,0 +1,12 @@
variable "ssh_key" {
type = string
default = "fediservices"
}
variable "instance_type" {
type = string
default = "t4g.nano"
}
variable "AWS_ACCESS_KEY_ID" {}
variable "AWS_SECRET_ACCESS_KEY" {}

38
vpc.tf Normal file
View file

@ -0,0 +1,38 @@
resource "aws_vpc" "vpc" {
cidr_block = "10.10.10.0/24"
enable_dns_hostnames = true
enable_dns_support = true
tags = {Name = "mainVPC"}
}
resource "aws_subnet" "subnet" {
count = length(data.aws_availability_zones.available.names)
vpc_id = aws_vpc.vpc.id
cidr_block = "10.10.10.${16*count.index}/28"
availability_zone= "${data.aws_availability_zones.available.names[count.index]}"
tags = {Name = "mainSubnet"}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {Name = "mainIGW"}
}
data "aws_route_table" "rt" {
vpc_id = aws_vpc.vpc.id
}
resource "aws_route" "igw" {
route_table_id = data.aws_route_table.rt.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
resource "aws_route_table_association" "association" {
count = length(data.aws_availability_zones.available.names)
subnet_id = element(aws_subnet.subnet.*.id, count.index)
route_table_id = data.aws_route_table.rt.id
}