Compare commits

...

3 Commits

Author SHA1 Message Date
Max
5ec2bd0c35 feat: moved to git subdomain 2025-02-11 23:10:57 -05:00
Max
116c683300 fix: restore command now seperated 2025-02-11 21:18:55 -05:00
Max
f7a0a3e868 feat: separated taskfiles 2025-02-11 16:30:21 -05:00
15 changed files with 113 additions and 75 deletions

View File

@@ -1,23 +1,16 @@
version: 3 version: 3
env: { TF: terraform -chdir=terraform }
silent: true silent: true
includes:
tf: { taskfile: terraform, dir: terraform }
tasks: tasks:
dev: docker compose -f compose.dev.yml up --build --force-recreate --no-deps dev: docker compose -f compose.dev.yml up --build --force-recreate --no-deps
tf/init: $TF init -backend-config=backend.tfvars
tf/plan: $TF plan -var-file=secret.tfvars
tf/destroy: $TF destroy
tf/format: $TF fmt -recursive
tf/apply:
- $TF apply -var-file=secret.tfvars
- $TF output -json > secrets.tf.json
tf/import:
- $TF import -var-file=secret.tfvars {{.CLI_ARGS}}
build: ansible-playbook playbooks/build.yml build: ansible-playbook playbooks/build.yml
deploy: ansible-playbook playbooks/deploy.yml deploy: ansible-playbook playbooks/deploy.yml
restore: ansible-playbook playbooks/restore.yml restore: ansible-playbook playbooks/restore.yml -e "restore_bucket={{.BUCKET}} restore_key={{.KEY}}"
run: run:
- task: build - task: build
- task: deploy - task: deploy
@@ -25,14 +18,14 @@ tasks:
enter: enter:
cmd: aws ssm start-session --target $INSTANCE_ID cmd: aws ssm start-session --target $INSTANCE_ID
env: env:
INSTANCE_ID: { sh: jq -r .instance_id.value < secrets.tf.json } INSTANCE_ID: { sh: jq -r .instance_id.value < config/infrastructure.secret.tf.json }
AWS_REGION: { sh: jq -r .aws_region < secrets/gitea.json } AWS_REGION: { sh: jq -r .aws_region < config/ansible.secret.json }
AWS_ACCESS_KEY_ID: { sh: jq -r .aws_access_key < secrets/gitea.json } AWS_ACCESS_KEY_ID: { sh: jq -r .aws_access_key < config/ansible.secret.json }
AWS_SECRET_ACCESS_KEY: { sh: jq -r .aws_secret_key < secrets/gitea.json } AWS_SECRET_ACCESS_KEY: { sh: jq -r .aws_secret_key < config/ansible.secret.json }
prune: push:
- docker system prune -af dir: gitea
- docker image prune -af cmds:
- docker system prune -af --volumes - docker build -t web/git . -f Dockerfile --platform linux/amd64,linux/arm64
- docker volume prune -af - docker login code.maximhutz.com
- docker system df - defer: docker logout

View File

@@ -2,8 +2,4 @@ FROM gitea/gitea:latest-rootless
ADD --chown=git:git config /etc/gitea ADD --chown=git:git config /etc/gitea
ADD --chown=git:git custom /etc/gitea-custom ADD --chown=git:git custom /etc/gitea-custom
ENV GITEA_CUSTOM /etc/gitea-custom ENV GITEA_CUSTOM=/etc/gitea-custom
WORKDIR /etc/gitea-custom
RUN gitea cert --host localhost --ca

View File

@@ -2,11 +2,11 @@ FROM gitea/gitea:latest-rootless
ADD --chown=git:git config /etc/gitea ADD --chown=git:git config /etc/gitea
ADD --chown=git:git custom /etc/gitea-custom ADD --chown=git:git custom /etc/gitea-custom
ENV GITEA_CUSTOM /etc/gitea-custom ENV GITEA_CUSTOM=/etc/gitea-custom
RUN rm /etc/gitea/app.ini RUN rm /etc/gitea/app.ini
RUN mv /etc/gitea/dev.app.ini /etc/gitea/app.ini RUN mv /etc/gitea/dev.app.ini /etc/gitea/app.ini
WORKDIR /etc/gitea-custom WORKDIR /etc/gitea-custom
RUN gitea cert --host code.maximhutz.com --ca RUN gitea cert --host localhost --ca

View File

@@ -24,31 +24,31 @@ DISABLE_SSH = false
START_SSH_SERVER = true START_SSH_SERVER = true
SSH_PORT = 22 SSH_PORT = 22
SSH_LISTEN_PORT = 22 SSH_LISTEN_PORT = 22
SSH_DOMAIN = code.maximhutz.com SSH_DOMAIN = git.maximhutz.com
BUILTIN_SSH_SERVER_USER = git BUILTIN_SSH_SERVER_USER = git
; --- Signed SSL --- ; --- Signed SSL ---
; PROTOCOL=https PROTOCOL=https
; ENABLE_ACME=true ENABLE_ACME=true
; ACME_ACCEPTTOS=true ACME_ACCEPTTOS=true
; ACME_DIRECTORY=https ACME_DIRECTORY=https
; ACME_EMAIL=proxy@maximhutz.com ACME_EMAIL=proxy@maximhutz.com
; DOMAIN = code.maximhutz.com DOMAIN = git.maximhutz.com
; ROOT_URL = https://code.maximhutz.com/ ROOT_URL = https://git.maximhutz.com/
; HTTP_PORT = 443 HTTP_PORT = 443
; --- No SSL --- ; --- No SSL ---
; DOMAIN = code.maximhutz.com ; DOMAIN = git.maximhutz.com
; ROOT_URL = http://code.maximhutz.com/ ; ROOT_URL = http://git.maximhutz.com/
; HTTP_PORT = 80 ; HTTP_PORT = 80
; --- Self-Signed SSL --- ; --- Self-Signed SSL ---
PROTOCOL = https # PROTOCOL = https
ROOT_URL = https://code.maximhutz.com/ # ROOT_URL = https://git.maximhutz.com/
DOMAIN = code.maximhutz.com # DOMAIN = git.maximhutz.com
HTTP_PORT = 443 # HTTP_PORT = 443
CERT_FILE = cert.pem # CERT_FILE = cert.pem
KEY_FILE = key.pem # KEY_FILE = key.pem
[database] [database]
DB_TYPE = sqlite3 DB_TYPE = sqlite3

View File

@@ -1,6 +1,7 @@
- name: Make build artifact. - name: Make build artifact.
hosts: localhost hosts: localhost
vars_files: ../secrets/gitea.json vars_files: ../config/ansible.secret.json
gather_facts: false
tasks: tasks:
- name: Build image. - name: Build image.
community.docker.docker_image_build: community.docker.docker_image_build:

View File

@@ -1,9 +1,10 @@
- name: Deploy artifact to instance. - name: Deploy artifact to instance.
hosts: localhost hosts: localhost
become: true become: true
gather_facts: false
vars_files: vars_files:
- ../secrets/gitea.json - ../config/ansible.secret.json
- ../secrets.tf.json - ../config/infrastructure.secret.tf.json
vars: vars:
ansible_connection: aws_ssm ansible_connection: aws_ssm
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
@@ -26,15 +27,17 @@
access_key: "{{ aws_access_key }}" access_key: "{{ aws_access_key }}"
secret_key: "{{ aws_secret_key }}" secret_key: "{{ aws_secret_key }}"
- name: Create data directory.
ansible.builtin.file:
path: /home/ssm-user/data
state: directory
mode: '0777'
- name: Load image. - name: Load image.
community.docker.docker_image_load: community.docker.docker_image_load:
path: /root/image.tar.gz path: /root/image.tar.gz
register: image register: image
- name: Create a volume.
community.docker.docker_volume:
name: data
- name: Run image. - name: Run image.
community.docker.docker_container: community.docker.docker_container:
name: server name: server

View File

@@ -1,9 +1,10 @@
- name: Deploy artifact to instance. - name: Deploy artifact to instance.
hosts: localhost hosts: localhost
become: true become: true
gather_facts: false
vars_files: vars_files:
- ../secrets/gitea.json - ../config/ansible.secret.json
- ../secrets.tf.json - ../config/infrastructure.secret.tf.json
vars: vars:
ansible_connection: aws_ssm ansible_connection: aws_ssm
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
@@ -27,23 +28,38 @@
access_key: "{{ boot_id.value }}" access_key: "{{ boot_id.value }}"
secret_key: "{{ boot_secret.value }}" secret_key: "{{ boot_secret.value }}"
amazon.aws.s3_object: amazon.aws.s3_object:
bucket: "{{ boot_bucket }}" bucket: "{{ restore_bucket | mandatory(msg='You must specify the bucket of the data.') }}"
object: "{{ boot_key }}" object: "{{ restore_key | mandatory(msg='You must specify the key of the data.') }}"
dest: /home/ssm-user/backup.tar.xz dest: /home/ssm-user/backup.tar.gz
mode: get mode: get
- name: Ensure backup directory exists. - name: Ensure backup directory exists.
ansible.builtin.file: ansible.builtin.file:
path: /home/ssm-user/data path: /home/ssm-user/backup
state: directory state: directory
mode: '0777' mode: '0777'
- name: Extract backup. - name: Extract backup.
ansible.builtin.unarchive: ansible.builtin.unarchive:
src: /home/ssm-user/backup.tar.xz src: /home/ssm-user/backup.tar.gz
dest: /home/ssm-user/data dest: /home/ssm-user/backup
remote_src: true remote_src: true
- name: Move backup files to data folder.
ansible.builtin.copy:
remote_src: true
src: /home/ssm-user/backup/backup/my-app-backup/
dest: /home/ssm-user/data/
mode: '0777'
- name: Update permissions.
ansible.builtin.file:
path: /home/ssm-user/data
recurse: true
mode: '0777'
owner: 1000
group: 1000
- name: Restart containers. - name: Restart containers.
community.docker.docker_container: community.docker.docker_container:
name: "{{ item }}" name: "{{ item }}"

18
terraform/Taskfile.yml Normal file
View File

@@ -0,0 +1,18 @@
version: 3
silent: true
vars:
BACKEND: ../config/backend.secret.tf.json
VARIABLES: ../config/variables.secret.tf.json
OUTPUT: ../config/infrastructure.secret.tf.json
tasks:
init: terraform init -backend-config={{.BACKEND}}
plan: terraform plan -var-file={{.VARIABLES}}
destroy: terraform destroy
format: terraform fmt -recursive
out: terraform output -json > {{.OUTPUT}}
apply:
- terraform apply -var-file={{.VARIABLES}}
- task: out
import: terraform import -var-file={{.VARIABLES}} {{.CLI_ARGS}}

View File

@@ -4,8 +4,8 @@ data "aws_s3_bucket" "storage_bucket" {
data "aws_iam_policy_document" "boot" { data "aws_iam_policy_document" "boot" {
statement { statement {
effect = "Allow" effect = "Allow"
actions = ["s3:*", "s3-object-lambda:*"] actions = ["s3:*", "s3-object-lambda:*"]
resources = [ resources = [
"${data.aws_s3_bucket.storage_bucket.arn}/${var.boot_key}", "${data.aws_s3_bucket.storage_bucket.arn}/${var.boot_key}",
"${data.aws_s3_bucket.storage_bucket.arn}/${var.boot_key}/*", "${data.aws_s3_bucket.storage_bucket.arn}/${var.boot_key}/*",

View File

@@ -6,7 +6,6 @@ amazon-linux-extras install docker ansible2 python3.8 -y
# Make Docker work. # Make Docker work.
systemctl enable docker systemctl enable docker
systemctl start docker systemctl start docker
sudo usermod -aG docker ssm-user
# Set up the correct version of Python (for Ansible). # Set up the correct version of Python (for Ansible).
ln -sf /usr/bin/python3.8 /usr/bin/python3 ln -sf /usr/bin/python3.8 /usr/bin/python3
@@ -26,3 +25,6 @@ service sshd stop
# Install Docker Compose. # Install Docker Compose.
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
# ERROR: SSM User not created yet.
sudo usermod -aG docker ssm-user

View File

@@ -1,6 +1,6 @@
# An elastic IP, so if the reverse proxy is modified, the route tables won't. # An elastic IP, so if the reverse proxy is modified, the route tables won't.
resource "aws_eip" "public" { resource "aws_eip" "public" {
instance = aws_instance.gitea.id instance = aws_instance.this.id
domain = "vpc" domain = "vpc"
} }
@@ -9,7 +9,7 @@ data "aws_iam_instance_profile" "ssm" {
} }
# The Gitea instance. # The Gitea instance.
resource "aws_instance" "gitea" { resource "aws_instance" "this" {
# ami = data.aws_ami.amazon-linux-2.id # ami = data.aws_ami.amazon-linux-2.id
ami = "ami-0adec96dc0cdc7bca" ami = "ami-0adec96dc0cdc7bca"
instance_type = "t4g.nano" instance_type = "t4g.nano"
@@ -20,6 +20,10 @@ resource "aws_instance" "gitea" {
iam_instance_profile = data.aws_iam_instance_profile.ssm.name iam_instance_profile = data.aws_iam_instance_profile.ssm.name
vpc_security_group_ids = [aws_security_group.public_access.id] vpc_security_group_ids = [aws_security_group.public_access.id]
metadata_options {
http_tokens = "required"
}
root_block_device { root_block_device {
volume_type = "gp3" volume_type = "gp3"
@@ -30,3 +34,8 @@ resource "aws_instance" "gitea" {
Name = "Codebase: Gitea" Name = "Codebase: Gitea"
} }
} }
resource "aws_ec2_instance_state" "this" {
instance_id = aws_instance.this.id
state = "running"
}

View File

@@ -20,7 +20,7 @@ module "vpc" {
public_subnets = [cidrsubnet(local.vpc_cidr, 8, 4)] public_subnets = [cidrsubnet(local.vpc_cidr, 8, 4)]
private_subnet_tags = { SubnetOf = "Main", SubnetType = "Private" } private_subnet_tags = { SubnetOf = "Main", SubnetType = "Private" }
public_subnet_tags = { SubnetOf = "Main", SubnetType = "Public" } public_subnet_tags = { SubnetOf = "Main", SubnetType = "Public" }
map_public_ip_on_launch = true map_public_ip_on_launch = true
enable_dns_hostnames = true enable_dns_hostnames = true

View File

@@ -1,27 +1,27 @@
output "instance_id" { output "instance_id" {
value = aws_instance.gitea.id value = aws_instance.this.id
description = "The instance ID of the Gitea instance." description = "The instance ID of the Gitea instance."
} }
output "ip_address" { output "ip_address" {
value = aws_instance.gitea.private_ip value = aws_instance.this.private_ip
description = "The Gitea IP address." description = "The Gitea IP address."
} }
output "boot_region" { output "boot_region" {
value = var.aws_region value = var.aws_region
description = "The region to manipulate the codebase repository boot." description = "The region to manipulate the codebase repository boot."
sensitive = true sensitive = true
} }
output "boot_id" { output "boot_id" {
value = module.boot_user.iam_access_key_id value = module.boot_user.iam_access_key_id
description = "The access id to manipulate the codebase repository boot." description = "The access id to manipulate the codebase repository boot."
sensitive = true sensitive = true
} }
output "boot_secret" { output "boot_secret" {
value = module.boot_user.iam_access_key_secret value = module.boot_user.iam_access_key_secret
description = "The access secret to manipulate the codebase repository boot." description = "The access secret to manipulate the codebase repository boot."
sensitive = true sensitive = true
} }

View File

@@ -6,7 +6,7 @@ data "aws_route53_zone" "main" {
# Push all domain traffic through the reverse proxy. # Push all domain traffic through the reverse proxy.
resource "aws_route53_record" "domain" { resource "aws_route53_record" "domain" {
zone_id = data.aws_route53_zone.main.zone_id zone_id = data.aws_route53_zone.main.zone_id
name = "code.${data.aws_route53_zone.main.name}" name = "git.${data.aws_route53_zone.main.name}"
type = "A" type = "A"
ttl = "60" ttl = "60"
records = [aws_eip.public.public_ip] records = [aws_eip.public.public_ip]

View File

@@ -14,16 +14,16 @@ variable "aws_secret" {
} }
variable "boot_bucket" { variable "boot_bucket" {
type = string type = string
description = "The name of the bucket to store the boot in." description = "The name of the bucket to store the boot in."
} }
variable "boot_key" { variable "boot_key" {
type = string type = string
description = "The path that will hold the boot data." description = "The path that will hold the boot data."
} }
variable "boot_role" { variable "boot_role" {
type = string type = string
description = "The name of the role for boot access." description = "The name of the role for boot access."
} }