mirror of
https://github.com/idanoo/fediservices.nz-infra
synced 2025-07-01 05:42:14 +00:00
Create infra
This commit is contained in:
parent
1bb150d44e
commit
2d32a3c4bb
9 changed files with 278 additions and 34 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -37,4 +37,6 @@ override.tf.json
|
|||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
.terraform.lock.hcl
|
||||
.terraform
|
||||
# End of https://www.toptal.com/developers/gitignore/api/terraform
|
||||
|
|
|
@ -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
55
ec2.tf
|
@ -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
93
iam.tf
Normal 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
40
sg.tf
Normal 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
9
template.tf
Normal 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
|
||||
}
|
||||
}
|
|
@ -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
12
variables.tf
Normal 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
38
vpc.tf
Normal 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue