From eec96b743aa01aef964c3d9712050d9bc2878b79 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 12 Jan 2025 02:25:31 -0500 Subject: [PATCH] feat: moved completely over to this repository --- .gitignore | 2 ++ Taskfile.yml | 26 +++++++++++++++++ playbooks/build.yml | 41 ++++++++++++++++++++++++++ playbooks/deploy.yml | 55 +++++++++++++++++++++++++++++++++++ requirements.txt | 41 ++++++++++++++++++++++++++ terraform/.terraform.lock.hcl | 24 +++++++++++++++ terraform/iam.tf | 23 +++++++-------- terraform/install.sh | 23 +++++++++++++++ terraform/main.tf | 2 +- terraform/network.tf | 6 ++++ terraform/output.tf | 6 ++-- terraform/providers.tf | 11 +++++++ terraform/variables.tf | 17 +++++++---- 13 files changed, 254 insertions(+), 23 deletions(-) create mode 100644 Taskfile.yml create mode 100644 playbooks/build.yml create mode 100644 playbooks/deploy.yml create mode 100644 requirements.txt create mode 100644 terraform/.terraform.lock.hcl create mode 100755 terraform/install.sh create mode 100644 terraform/network.tf create mode 100644 terraform/providers.tf diff --git a/.gitignore b/.gitignore index 146575e..40f0583 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ override.tf.json .terraformrc terraform.rc +*secret* +.vscode \ No newline at end of file diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..9bd658e --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,26 @@ +version: 3 +env: { TF: terraform -chdir=terraform } +silent: true + +tasks: + 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 + + build: ansible-playbook playbooks/build.yml + deploy: ansible-playbook playbooks/deploy.yml + run: + - task: build + - task: deploy + + enter: + cmd: aws ssm start-session --target $INSTANCE_ID + env: + INSTANCE_ID: { sh: jq -r .instance_id.value < secrets.tf.json } + AWS_REGION: { sh: jq -r .aws_region < secrets/gitea.json } + AWS_ACCESS_KEY_ID: { sh: jq -r .aws_access_key < secrets/gitea.json } + AWS_SECRET_ACCESS_KEY: { sh: jq -r .aws_secret_key < secrets/gitea.json } diff --git a/playbooks/build.yml b/playbooks/build.yml new file mode 100644 index 0000000..4b3c57f --- /dev/null +++ b/playbooks/build.yml @@ -0,0 +1,41 @@ +- name: Make build artifact. + hosts: localhost + vars_files: ../secrets/gitea.json + tasks: + - name: Build image. + community.docker.docker_image_build: + name: "{{ image_name }}" + path: ../image + nocache: true + rebuild: always + pull: true + + - name: Make temp file. + ansible.builtin.tempfile: + suffix: .tar + register: tar_file + + - name: Push image to archive. + community.docker.docker_image: + name: "{{ image_name }}" + archive_path: "{{ tar_file.path }}" + source: local + + - name: Compress archive to artifact. + register: compress_image + community.general.archive: + path: "{{ tar_file.path }}" + dest: "{{ tar_file.path }}.xz" + format: xz + mode: "0644" + + - name: Push artifact to S3. + amazon.aws.s3_object: + bucket: "{{ image_bucket }}" + object: "{{ image_key }}" + src: "{{ tar_file.path }}.xz" + mode: put + + region: "{{ aws_region }}" + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml new file mode 100644 index 0000000..bcb13c6 --- /dev/null +++ b/playbooks/deploy.yml @@ -0,0 +1,55 @@ +- name: Deploy artifact to instance. + hosts: localhost + become: true + vars_files: + - ../secrets/gitea.json + - ../secrets.tf.json + vars: + ansible_connection: aws_ssm + ansible_python_interpreter: /usr/bin/python3 + ansible_aws_ssm_plugin: "{{ ssm_plugin }}" + ansible_aws_ssm_bucket_name: "{{ image_bucket }}" + ansible_aws_ssm_instance_id: "{{ instance_id.value }}" + + ansible_aws_ssm_region: "{{ aws_region }}" + ansible_aws_ssm_access_key_id: "{{ aws_access_key }}" + ansible_aws_ssm_secret_access_key: "{{ aws_secret_key }}" + tasks: + - name: Fetch image. + amazon.aws.s3_object: + mode: get + bucket: "{{ image_bucket }}" + object: "{{ image_key }}" + dest: /root/image.tar.xz + + region: "{{ aws_region }}" + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" + + - name: Load image. + community.docker.docker_image_load: + path: /root/image.tar.xz + register: image + + - name: Run image. + community.docker.docker_container: + name: server + image: "{{ image.image_names[0] }}" + state: started + recreate: true + restart_policy: unless-stopped + memory: 425m + memory_swap: 900m + ports: [80:80, 2222:2222] + env: + GITEA__security__INTERNAL_TOKEN: "{{ internal_secret }}" + GITEA__server__LFS_JWT_SECRET: "{{ lfs_secret }}" + GITEA__oauth2__JWT_SECRET: "{{ jwt_secret }}" + AWS_REGION: "{{ boot_region.value }}" + AWS_ACCESS_KEY_ID: "{{ boot_id.value }}" + AWS_SECRET_ACCESS_KEY: "{{ boot_secret.value }}" + BOOT_URI: "s3://{{ boot_bucket }}/{{ boot_key }}" + volumes: + - /root/boot:/var/lib/gitea + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f1246e9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,41 @@ +ansible==11.1.0 +ansible-compat==24.10.0 +ansible-core==2.18.1 +ansible-lint==24.12.2 +attrs==24.3.0 +black==24.10.0 +boto3==1.35.95 +botocore==1.35.95 +bracex==2.5.post1 +certifi==2024.12.14 +cffi==1.17.1 +charset-normalizer==3.4.1 +click==8.1.8 +cryptography==44.0.0 +filelock==3.16.1 +idna==3.10 +importlib_metadata==8.5.0 +Jinja2==3.1.5 +jmespath==1.0.1 +jsonschema==4.23.0 +jsonschema-specifications==2024.10.1 +MarkupSafe==3.0.2 +mypy-extensions==1.0.0 +packaging==24.2 +pathspec==0.12.1 +platformdirs==4.3.6 +pycparser==2.22 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +referencing==0.35.1 +requests==2.32.3 +resolvelib==1.0.1 +rpds-py==0.22.3 +ruamel.yaml==0.18.10 +s3transfer==0.10.4 +six==1.17.0 +subprocess-tee==0.4.2 +urllib3==2.3.0 +wcmatch==10.0 +yamllint==1.35.1 +zipp==3.21.0 diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 0000000..8b9ee2c --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,24 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.83.1" + hashes = [ + "h1:Yy3K7R7881H72rQDzG6qjZVkrWA6DGJzfE21TionY7w=", + "zh:0313253c78f195973752c4d1f62bfdd345a9c99c1bc7a612a8c1f1e27d51e49e", + "zh:108523f3e9ebc93f7d900c51681f6edbd3f3a56b8a62b0afc31d8214892f91e0", + "zh:175b9bf2a00bea6ac1c73796ad77b0e00dcbbde166235017c49377d7763861d8", + "zh:1c8bf55b8548bbad683cd6d7bdb03e8840a00b2422dc1529ffb9892820657130", + "zh:22338f09bae62d5ff646de00182417f992548da534fee7d98c5d0136d4bd5d7a", + "zh:92de1107ec43de60612be5f6255616f16a9cf82d88df1af1c0471b81f3a82c16", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9c7bfb7afea330e6d90e1466125a8cba3db1ed4043c5da52f737459c89290a6e", + "zh:ba59b374d477e5610674b70f5abfe0408e8f809390347372751384151440d3d0", + "zh:bd1c433966002f586d63cb1e3e16326991f238bc6beeb2352be36ec651917b0b", + "zh:ca2b4d1d02651c15261fffa4b142e45def9a22c6069353f0f663fd2046e268f8", + "zh:d8ed98c748f7a3f1a72277cfee9afe346aca39ab319d17402277852551d8f14a", + "zh:ed3d8bc89de5f35f3c5f4802ff7c749fda2e2be267f9af4a850694f099960a72", + "zh:f698732a4391c3f4d7079b4aaa52389da2a460cac5eed438ed688f147d603689", + "zh:f9f51b17f2978394954e9f6ab9ef293b8e11f1443117294ccf87f7f8212b3439", + ] +} diff --git a/terraform/iam.tf b/terraform/iam.tf index 4dac585..2a9e402 100644 --- a/terraform/iam.tf +++ b/terraform/iam.tf @@ -2,7 +2,7 @@ data "aws_s3_bucket" "storage_bucket" { bucket = var.boot_bucket } -data "aws_iam_policy_document" "gitea_bool_policy" { +data "aws_iam_policy_document" "boot" { statement { effect = "Allow" actions = ["s3:*", "s3-object-lambda:*"] @@ -10,22 +10,19 @@ data "aws_iam_policy_document" "gitea_bool_policy" { } } -resource "aws_iam_policy" "gitea_boot_policy" { +resource "aws_iam_policy" "boot" { name = "${var.boot_role}Policy" description = "The policy that manages the Gitea Boot." - policy = data.aws_iam_policy_document.gitea_bool_policy.json + policy = data.aws_iam_policy_document.boot.json } -resource "aws_iam_user" "gitea_boot_user" { +module "boot_user" { + source = "terraform-aws-modules/iam/aws//modules/iam-user" + version = "5.52.2" + + create_iam_user_login_profile = false name = "${var.boot_role}User" + password_reset_required = false + policy_arns = [aws_iam_policy.boot.arn] } - -resource "aws_iam_user_policy_attachment" "attachment" { - user = aws_iam_user.gitea_boot_user.name - policy_arn = aws_iam_policy.gitea_boot_policy.arn -} - -resource "aws_iam_access_key" "gitea_boot_key" { - user = aws_iam_user.gitea_boot_user.name -} \ No newline at end of file diff --git a/terraform/install.sh b/terraform/install.sh new file mode 100755 index 0000000..19a3273 --- /dev/null +++ b/terraform/install.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +amazon-linux-extras install docker ansible2 python3.8 -y + +# Make Docker work. +systemctl enable docker +systemctl start docker +sudo usermod -a -G docker ssm-user + +# Set up the correct version of Python (for Ansible). +ln -sf /usr/bin/python3.8 /usr/bin/python3 +ln -sf /usr/bin/pip3.8 /usr/bin/pip3 +pip3 install botocore boto3 requests +python3 -m pip install -U pip + +# Add some swap space. +dd if=/dev/zero of=/swapfile bs=128M count=8 +chmod 600 /swapfile +mkswap /swapfile +swapon /swapfile + +# Stop SSH (because we have SSM.) +sudo service sshd stop \ No newline at end of file diff --git a/terraform/main.tf b/terraform/main.tf index dda419f..11849a4 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -7,7 +7,7 @@ resource "aws_instance" "gitea" { # ami = data.aws_ami.amazon-linux-2.id ami = "ami-0adec96dc0cdc7bca" instance_type = "t4g.nano" - subnet_id = var.subnet + subnet_id = data.aws_subnet.subnet.id user_data = file("install.sh") user_data_replace_on_change = true diff --git a/terraform/network.tf b/terraform/network.tf new file mode 100644 index 0000000..1df9cff --- /dev/null +++ b/terraform/network.tf @@ -0,0 +1,6 @@ +data "aws_subnet" "subnet" { + tags = { + SubnetType = "Private" + SubnetOf = "Main" + } +} diff --git a/terraform/output.tf b/terraform/output.tf index 72e36a3..9797cd9 100644 --- a/terraform/output.tf +++ b/terraform/output.tf @@ -9,19 +9,19 @@ output "ip_address" { } output "boot_region" { - value = var.region + value = var.aws_region description = "The region to manipulate the codebase repository boot." sensitive = true } output "boot_id" { - value = aws_iam_access_key.gitea_boot_key.id + value = module.boot_user.iam_access_key_id description = "The access id to manipulate the codebase repository boot." sensitive = true } output "boot_secret" { - value = aws_iam_access_key.gitea_boot_key.secret + value = module.boot_user.iam_access_key_secret description = "The access secret to manipulate the codebase repository boot." sensitive = true } diff --git a/terraform/providers.tf b/terraform/providers.tf new file mode 100644 index 0000000..d97d5b4 --- /dev/null +++ b/terraform/providers.tf @@ -0,0 +1,11 @@ +terraform { + # The backend is stored in an S3 bucket. + backend "s3" {} +} + +# Access AWS through the IaC roles. +provider "aws" { + region = var.aws_region + access_key = var.aws_access + secret_key = var.aws_secret +} \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf index 75e36f2..2eb970a 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -1,8 +1,18 @@ -variable "region" { +variable "aws_region" { type = string description = "The AWS region things are created in." } +variable "aws_access" { + type = string + description = "The access key to generate the Gitea instance." +} + +variable "aws_secret" { + type = string + description = "The access secret to generate the Gitea instance." +} + variable "boot_bucket" { type = string description = "The name of the bucket to store the boot in." @@ -17,8 +27,3 @@ variable "boot_role" { type = string description = "The name of the role for boot access." } - -variable "subnet" { - type = string - description = "The ID of the subnet that the instance will be housed in." -} \ No newline at end of file