mirror of https://gitlab.com/bashrc2/epicyon
Merge pull request #2 from n4veenkumar/infra-provisioning
Infra provisioning of AWS for Epicyonmain
commit
fc636a2126
|
@ -0,0 +1,20 @@
|
|||
**/.terraform/*
|
||||
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform.lock.hcl
|
||||
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
*.tfvars
|
||||
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
*tfplan*
|
||||
|
||||
.terraformrc
|
||||
terraform.rc
|
|
@ -0,0 +1,54 @@
|
|||
# terraform-aws-epicyon
|
||||
|
||||
This repo contains a Terraform plan for deploying Epicyon on an AWS EC2 instance
|
||||
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
| ---- | ------- |
|
||||
| terraform | >=v1.0.7 |
|
||||
| aws | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
|Name | Version |
|
||||
| --- | ------- |
|
||||
| aws | ~> 4.0 |
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [aws_eip.epicyon](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
|
||||
| [aws_eip_association.epicyon](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip_association) | resource |
|
||||
| [aws_iam_instance_profile.epicyon_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
|
||||
| [aws_iam_policy_attachment.epicyon](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource |
|
||||
| [aws_iam_role.epicyon_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
|
||||
| [aws_instance.epicyon_web](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource |
|
||||
| [aws_ami.ubuntu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
|
||||
| [aws_security_group.epicyon_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
|
||||
| [aws_vpc.epicyon_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource |
|
||||
| [aws_subnet.epicyon_subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
|
||||
| [aws_internet_gateway.epicyon_gw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
|
||||
| [aws_route_table.epicyon_route_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
|
||||
| [aws_route_table_association.epicyon_route_table_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| vpc_cidr_block | The IPv4 CIDR block for the VPC | `number` | `""` | yes |
|
||||
| subnet_cidr | The IPv4 CIDR block for the subnet | `number` | `""` | yes |
|
||||
| route_cidr_block | The CIDR block of the route | `number` | `""` | yes |
|
||||
| key_name | Key name of the Key Pair to use for the instance | `string` | `""` | yes |
|
||||
| instance\_type | The instance type to use for the instance. | `string` | `"t2.micro"` | no |
|
||||
| domain | A public domain for Epicyon | `string` | `""` | yes |
|
||||
| email | Email used to order a certificate from Let's Encrypt | `string` | `""` | yes |
|
||||
|
||||
## Output
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
| ipv4_address | The public IP address of the epicyon instance |
|
||||
| domain_name | The URL to epicyon |
|
|
@ -0,0 +1,136 @@
|
|||
locals {
|
||||
user_data_vars = {
|
||||
domain = var.domain
|
||||
email = var.email
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc" "epicyon_vpc" {
|
||||
cidr_block = var.vpc_cidr_block
|
||||
|
||||
tags = {
|
||||
Name = "epicyon_vpc"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_subnet" "epicyon_subnet" {
|
||||
vpc_id = aws_vpc.epicyon_vpc.id
|
||||
cidr_block = var.subnet_cidr
|
||||
|
||||
tags = {
|
||||
Name = "epicyon_subnet"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_internet_gateway" "epicyon_gw" {
|
||||
vpc_id = aws_vpc.epicyon_vpc.id
|
||||
|
||||
tags = {
|
||||
Name = "epicyon_gw"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table" "epicyon_route_table" {
|
||||
vpc_id = aws_vpc.epicyon_vpc.id
|
||||
|
||||
route {
|
||||
cidr_block = var.route_cidr_block
|
||||
gateway_id = aws_internet_gateway.epicyon_gw.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "epicyon_route_table_association" {
|
||||
subnet_id = aws_subnet.epicyon_subnet.id
|
||||
route_table_id = aws_route_table.epicyon_route_table.id
|
||||
}
|
||||
|
||||
resource "aws_security_group" "epicyon_sg" {
|
||||
name = "epicyon_sg"
|
||||
description = "Allow all incoming traffic"
|
||||
vpc_id = aws_vpc.epicyon_vpc.id
|
||||
|
||||
dynamic "ingress" {
|
||||
for_each = toset(var.domain == "" ? [8080] : [80, 443])
|
||||
content {
|
||||
cidr_blocks = [
|
||||
"0.0.0.0/0"
|
||||
]
|
||||
from_port = ingress.value
|
||||
to_port = ingress.value
|
||||
protocol = "tcp"
|
||||
}
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_ami" "ubuntu" {
|
||||
most_recent = true
|
||||
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
owners = ["099720109477"]
|
||||
}
|
||||
|
||||
resource "aws_instance" "epicyon_web" {
|
||||
ami = data.aws_ami.ubuntu.id
|
||||
iam_instance_profile = aws_iam_instance_profile.epicyon_instance_profile.id
|
||||
instance_type = var.instance_type
|
||||
associate_public_ip_address = true
|
||||
subnet_id = aws_subnet.epicyon_subnet.id
|
||||
vpc_security_group_ids = [aws_security_group.epicyon_sg.id]
|
||||
user_data = base64encode(templatefile("${path.module}/templates/startup.sh", local.user_data_vars))
|
||||
key_name = var.key_name
|
||||
tags = {
|
||||
Name = "epicyon_web"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "epicyon_iam_role" {
|
||||
name = "epicyon_iam_role"
|
||||
assume_role_policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [
|
||||
{
|
||||
Action = "sts:AssumeRole"
|
||||
Effect = "Allow"
|
||||
Sid = ""
|
||||
Principal = {
|
||||
Service = "ec2.amazonaws.com"
|
||||
}
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
resource "aws_iam_instance_profile" "epicyon_instance_profile" {
|
||||
name = var.profile
|
||||
role = aws_iam_role.epicyon_role.id
|
||||
}
|
||||
|
||||
resource "aws_iam_policy_attachment" "epicyon" {
|
||||
name = format("%s-attachment", epicyon)
|
||||
roles = [aws_iam_role.epicyon_role.id]
|
||||
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
|
||||
}
|
||||
|
||||
resource "aws_eip" "epicyon" {
|
||||
instance = aws_instance.epicyon_web.id
|
||||
vpc = true
|
||||
}
|
||||
|
||||
resource "aws_eip_association" "epicyon" {
|
||||
instance_id = aws_instance.epicyon_web.id
|
||||
allocation_id = aws_eip.elastic.id
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
output "epicyon_domain" {
|
||||
description = "The name of the record"
|
||||
value = format("https://%s", var.domain)
|
||||
}
|
||||
|
||||
output "ipv4_address" {
|
||||
description = "The instance ip"
|
||||
value = aws_instance.epicyon_web.public_ip
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export YOUR_DOMAIN=${domain}
|
||||
export YOUR_EMAIL=${email}
|
||||
|
||||
sudo apt update -y
|
||||
sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-cryptography python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget
|
||||
cd /opt || exit
|
||||
sudo git clone https://gitlab.com/bashrc2/epicyon
|
||||
cd /opt/epicyon || exit
|
||||
sudo adduser --system --home=/opt/epicyon --group epicyon
|
||||
sudo mkdir /var/www/${domain}
|
||||
sudo mkdir -p /opt/epicyon/accounts/newsmirror
|
||||
sudo ln -s /opt/epicyon/accounts/newsmirror /var/www/${domain}/newsmirror
|
||||
|
||||
sudo tee /tmp/epicyon.service >/dev/null <<EOF
|
||||
[Unit]
|
||||
Description=epicyon
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
[Service]
|
||||
Type=simple
|
||||
User=epicyon
|
||||
Group=epicyon
|
||||
WorkingDirectory=/opt/epicyon
|
||||
ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain ${domain} --registration open --log_login_failures
|
||||
Environment=USER=epicyon
|
||||
Environment=PYTHONUNBUFFERED=true
|
||||
Restart=always
|
||||
StandardError=syslog
|
||||
CPUQuota=80%
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelLogs=true
|
||||
ProtectHostname=true
|
||||
ProtectClock=true
|
||||
ProtectProc=invisible
|
||||
ProcSubset=pid
|
||||
PrivateTmp=true
|
||||
PrivateUsers=true
|
||||
PrivateDevices=true
|
||||
PrivateIPC=true
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
LockPersonality=true
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
RestrictNamespaces=true
|
||||
SystemCallArchitectures=native
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo mv /tmp/epicyon.service /etc/systemd/system/
|
||||
sudo chown -R epicyon:epicyon /opt/epicyon
|
||||
sudo systemctl daemon-reload && sudo systemctl start epicyon && sudo systemctl enable epicyon
|
||||
|
||||
sudo tee /tmp/${domain} >/dev/null <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${domain};
|
||||
access_log /dev/null;
|
||||
error_log /dev/null;
|
||||
client_max_body_size 31m;
|
||||
client_body_buffer_size 128k;
|
||||
|
||||
index index.html;
|
||||
rewrite ^ https://\$server_name\$request_uri? permanent;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name ${domain};
|
||||
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/ld+json application/javascript text/xml application/xml application/rdf+xml application/xml+rss text/javascript;
|
||||
|
||||
ssl_stapling off;
|
||||
ssl_stapling_verify off;
|
||||
ssl on;
|
||||
ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
add_header Content-Security-Policy "default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'";
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Download-Options noopen;
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
|
||||
|
||||
access_log /dev/null;
|
||||
error_log /dev/null;
|
||||
|
||||
index index.html;
|
||||
|
||||
location /newsmirror {
|
||||
root /var/www/${domain};
|
||||
try_files \$uri =404;
|
||||
}
|
||||
|
||||
keepalive_timeout 70;
|
||||
sendfile on;
|
||||
|
||||
location / {
|
||||
proxy_http_version 1.1;
|
||||
client_max_body_size 31M;
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forward-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forward-Proto http;
|
||||
proxy_set_header X-Nginx-Proxy true;
|
||||
proxy_temp_file_write_size 64k;
|
||||
proxy_connect_timeout 10080s;
|
||||
proxy_send_timeout 10080;
|
||||
proxy_read_timeout 10080;
|
||||
proxy_buffer_size 64k;
|
||||
proxy_buffers 16 32k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
proxy_redirect off;
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
proxy_pass http://localhost:7156;
|
||||
tcp_nodelay on;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
sudo mv /tmp/${domain} /etc/nginx/sites-available/
|
||||
sudo ln -s /etc/nginx/sites-available/${domain} /etc/nginx/sites-enabled/
|
||||
sudo systemctl stop nginx
|
||||
sudo certbot certonly -n --server https://acme-v02.api.letsencrypt.org/directory --standalone -d ${domain} --renew-by-default --agree-tos --email ${email}
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
variable "vpc_cidr_block" {
|
||||
type = number
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "subnet_cidr" {
|
||||
type = number
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "route_cidr_block" {
|
||||
type = number
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "key_name" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
type = string
|
||||
default = "t2.micro"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "email" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 4.0"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue