Compare commits
3 Commits
0c5a7ef7f3
...
5ec2bd0c35
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ec2bd0c35 | |||
| 116c683300 | |||
| f7a0a3e868 |
35
Taskfile.yml
35
Taskfile.yml
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
18
terraform/Taskfile.yml
Normal 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}}
|
||||||
@@ -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}/*",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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."
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user