From 9c14f49ef904cc78c63d679bb0900849ad789bf3 Mon Sep 17 00:00:00 2001 From: Andrew Burchill Date: Tue, 22 Oct 2024 13:02:23 +1100 Subject: [PATCH 1/2] Use templatefiles and expose auth token --- data.tf | 11 +- locals.tf | 383 ++--------------------------- main.tf | 10 +- outputs.tf | 14 +- templates/app.ini.tftpl | 106 ++++++++ templates/runner-config.yaml.tftpl | 96 ++++++++ templates/user-data.sh.tftpl | 77 ++++++ variables.tf | 64 +---- 8 files changed, 323 insertions(+), 438 deletions(-) create mode 100644 templates/app.ini.tftpl create mode 100644 templates/runner-config.yaml.tftpl create mode 100644 templates/user-data.sh.tftpl diff --git a/data.tf b/data.tf index 7ab4e7d..cb49744 100644 --- a/data.tf +++ b/data.tf @@ -1,3 +1,12 @@ data "aws_ssm_parameter" "amazon_linux_2023" { name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64" -} \ No newline at end of file +} + +data "http" "auth_token" { + depends_on = [aws_instance.gitea] + + method = "GET" + insecure = true + url = "http://${aws_instance.gitea.public_ip}:${var.token_port}/token" +} + diff --git a/locals.tf b/locals.tf index 9ac7fa6..b074d4b 100644 --- a/locals.tf +++ b/locals.tf @@ -1,365 +1,20 @@ locals { - user_data = <<-EOF -#!/bin/bash - -set -x - -touch /home/ec2-user/.user-data-started - -echo --- install docker --- -dnf update -y -dnf install -y nmap-ncat python3-pip python3 tmux htop git jq # TODO probably only need git -dnf install -y ${var.docker_version} -systemctl enable docker -systemctl start docker -newgrp - -echo --- setup gitea --- -docker pull -q ${var.image} -mkdir /etc/gitea /data -mkdir -vp /etc/gitea/gitea/conf/ -cat < /etc/gitea/gitea/conf/app.ini -${local.app_ini_config} -EOT -PUBLIC_IP=$(curl -s http://checkip.amazonaws.com) -sed -i s/PUBLIC_IP/$PUBLIC_IP/g /etc/gitea/gitea/conf/app.ini - -echo --- start gitea --- -docker network create gitea -docker run -d \ - --name gitea \ - --network gitea \ - --restart always \ - -e USER_UID=1000 \ - -e USER_GID=1000 \ - -v /etc/gitea:/data \ - -v /etc/timezone:/etc/timezone:ro \ - -v /etc/localtime:/etc/localtime:ro \ - -p ${var.external_port}:3000 \ - -p ${var.ssh_port}:22 \ - ${var.image} - -while [ "$(curl -s http://localhost:${var.external_port}/api/healthz | jq -r .status)" != "pass" ]; do sleep 2; done && echo "pass" - -echo ---create user --- -docker exec -u git gitea bash -c "/app/gitea/gitea migrate" -docker exec -u git gitea bash -c \ - "/app/gitea/gitea admin user create --username ${var.username} --email ${var.email} --password ${var.password}" - -if [ "${var.create_empty_repo}" = true ]; then - echo --- create emtpy repo --- - curl -X POST \ - -H "Content-Type: application/json" \ - -u "${var.username}:${var.password}" \ - -d '{"name": "${var.empty_repo_name}", "description": "${var.empty_repo_description}", "private": true}' \ - http://localhost:${var.external_port}/api/v1/user/repos -fi - -if [ "${var.create_cloned_repo}" = true ]; then - echo --- clone repo --- - ${local.clone_repo_function} - clone_public_repo_to_gitea \ - "http://${var.username}:${var.password}@$PUBLIC_IP:${var.external_port}" \ - "${var.username}" \ - "$(basename ${var.cloned_repo_source} .git)" \ - "${var.cloned_repo_source}" -fi - -if [ "${var.create_secret}" = true ]; then - echo --- creating secret --- - curl -X PUT \ - -H "Content-Type: application/json" \ - -H 'accept: application/json' \ - -u "${var.username}:${var.password}" \ - -d '{"data": "${var.secret_value}"}' \ - http://localhost:${var.external_port}/api/v1/user/actions/secrets/${var.secret_name} -fi - -if [ "${var.create_runner}" = true ]; then - echo --- pull runner image --- - docker pull -q ${var.runner_image} & - - echo --- install runner --- - curl -sL ${var.runner_binary_url} > /usr/local/bin/act - chmod +x /usr/local/bin/act - - echo --- create runner config --- - cat < ./runner.yaml - ${local.runner_config} -EOC - - echo --- register runner --- - RUNNER_TOKEN=$(docker exec -u git gitea bash -c "/app/gitea/gitea actions generate-runner-token") - act register --no-interactive --instance http://$PUBLIC_IP:${var.external_port} --token "$RUNNER_TOKEN" - - echo --- start runner --- - nohup act --config ./runner.yaml daemon & -fi - -echo --- gitea setup finished --- -touch /home/ec2-user/.gitea-ready -EOF - clone_repo_function = <<-EOF -# Bash function to clone a GitHub repository into a new Gitea repository -clone_public_repo_to_gitea() { - local GITEA_URL="$1" - local GITEA_USERNAME="$2" - local GITEA_REPO_NAME="$3" - local GITHUB_REPO_URL="$4" - - EMAIL="${var.email}" - NAME="${var.username}" - - # Create a new repo in Gitea - curl -X POST "$GITEA_URL/api/v1/user/repos" \ - -u "${var.username}:${var.password}" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "'"$GITEA_REPO_NAME"'", - "private": false, - "auto_init": false - }' - - # Check if the repo creation was successful - if [ $? -ne 0 ]; then - echo "Failed to create repository on Gitea" - return 1 - fi - - cd /tmp - - # Mirror clone the GitHub repository - git clone "$GITHUB_REPO_URL" - - if [ $? -ne 0 ]; then - echo "Failed to clone GitHub repository" - return 1 - fi - - # Extract the repo name from the GitHub URL - local REPO_DIR=$(basename "$GITHUB_REPO_URL" .git) - - # Push to the new Gitea repository - cd "$REPO_DIR" - git remote set-url origin "$GITEA_URL/$GITEA_USERNAME/$GITEA_REPO_NAME.git" - - git filter-branch -f --env-filter "GIT_AUTHOR_NAME=$NAME; GIT_AUTHOR_EMAIL=$EMAIL; GIT_COMMITTER_NAME=$NAME; GIT_COMMITTER_EMAIL=$EMAIL;" HEAD - #git rebase -r --root --exec "git commit --amend --no-edit --reset-author" - - git push # --mirror - - if [ $? -ne 0 ]; then - echo "Failed to push to Gitea repository" - return 1 - fi - - cd - - echo "Repository cloned successfully from GitHub to Gitea" -} -EOF - app_ini_config = <<-EOF -APP_NAME = Gitea: Git with a cup of tea -RUN_MODE = prod -RUN_USER = git -WORK_PATH = /data/gitea - -[repository] -ROOT = /data/git/repositories -DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions - -[repository.local] -LOCAL_COPY_PATH = /data/gitea/tmp/local-repo - -[repository.upload] -TEMP_PATH = /data/gitea/uploads - -[server] -APP_DATA_PATH = /data/gitea -DOMAIN = PUBLIC_IP -SSH_DOMAIN = PUBLIC_IP -HTTP_PORT = ${var.external_port} -ROOT_URL = http://PUBLIC_IP:${var.external_port}/ -DISABLE_SSH = false -SSH_PORT = ${var.ssh_port} -SSH_LISTEN_PORT = 22 -LFS_START_SERVER = true -LFS_JWT_SECRET = xqrgNapz38Zox2rfmA32TTdW5Ge1WIgsPUXsykJMIiw -OFFLINE_MODE = false - -[database] -PATH = /data/gitea/gitea.db -DB_TYPE = sqlite3 -HOST = localhost:3306 -NAME = gitea -USER = root -PASSWD = -LOG_SQL = false -SCHEMA = -SSL_MODE = disable - -[indexer] -ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve - -[session] -PROVIDER_CONFIG = /data/gitea/sessions -PROVIDER = file - -[picture] -AVATAR_UPLOAD_PATH = /data/gitea/avatars -REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars - -[attachment] -PATH = /data/gitea/attachments - -[log] -MODE = console -LEVEL = info -ROOT_PATH = /data/gitea/log - -[security] -INSTALL_LOCK = true -SECRET_KEY = -REVERSE_PROXY_LIMIT = 1 -REVERSE_PROXY_TRUSTED_PROXIES = * -INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MTQ5NTYwMTR9.7acb0biC_w1kt80Wd_DimlubtK9PfAOqk542r55JeXA -PASSWORD_HASH_ALGO = pbkdf2 - -[service] -DISABLE_REGISTRATION = false -REQUIRE_SIGNIN_VIEW = false -REGISTER_EMAIL_CONFIRM = false -ENABLE_NOTIFY_MAIL = false -ALLOW_ONLY_EXTERNAL_REGISTRATION = false -ENABLE_CAPTCHA = false -DEFAULT_KEEP_EMAIL_PRIVATE = false -DEFAULT_ALLOW_CREATE_ORGANIZATION = true -DEFAULT_ENABLE_TIMETRACKING = true -NO_REPLY_ADDRESS = noreply.localhost - -[lfs] -PATH = /data/git/lfs - -[mailer] -ENABLED = false - -[openid] -ENABLE_OPENID_SIGNIN = true -ENABLE_OPENID_SIGNUP = true - -[cron.update_checker] -ENABLED = false - -[repository.pull-request] -DEFAULT_MERGE_STYLE = merge - -[repository.signing] -DEFAULT_TRUST_MODEL = committer - -[oauth2] -JWT_SECRET = ${var.jwt_secret} - -[actions] -ENABLED=true - -[metrics] -ENABLED=true -EOF - runner_config = <<-EOF -# Example configuration file, it's safe to copy this as the default config file without any modification. - -# You don't have to copy this file to your instance, -# just run `./act_runner generate-config > config.yaml` to generate a config file. - -log: - # The level of logging, can be trace, debug, info, warn, error, fatal - level: info - -runner: - # Where to store the registration result. - file: .runner - # Execute how many tasks concurrently at the same time. - capacity: 1 - # Extra environment variables to run jobs. - envs: - A_TEST_ENV_NAME_1: a_test_env_value_1 - A_TEST_ENV_NAME_2: a_test_env_value_2 - # Extra environment variables to run jobs from a file. - # It will be ignored if it's empty or the file doesn't exist. - env_file: .env - # The timeout for a job to be finished. - # Please note that the Gitea instance also has a timeout (3h by default) for the job. - # So the job could be stopped by the Gitea instance if it's timeout is shorter than this. - timeout: 3h - # Whether skip verifying the TLS certificate of the Gitea instance. - insecure: false - # The timeout for fetching the job from the Gitea instance. - fetch_timeout: 5s - # The interval for fetching the job from the Gitea instance. - fetch_interval: 2s - # The labels of a runner are used to determine which jobs the runner can run, and how to run them. - # Like: "macos-arm64:host" or "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest" - # Find more images provided by Gitea at https://gitea.com/gitea/runner-images . - # If it's empty when registering, it will ask for inputting labels. - # If it's empty when execute `daemon`, will use labels in `.runner` file. - labels: - - "ubuntu-latest:docker://${var.runner_image}" - -cache: - # Enable cache server to use actions/cache. - enabled: true - # The directory to store the cache data. - # If it's empty, the cache data will be stored in $HOME/.cache/actcache. - dir: "" - # The host of the cache server. - # It's not for the address to listen, but the address to connect from job containers. - # So 0.0.0.0 is a bad choice, leave it empty to detect automatically. - host: "" - # The port of the cache server. - # 0 means to use a random available port. - port: 0 - # The external cache server URL. Valid only when enable is true. - # If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself. - # The URL should generally end with "/". - external_server: "" - -container: - # Specifies the network to which the container will connect. - # Could be host, bridge or the name of a custom network. - # If it's empty, act_runner will create a network automatically. - network: "" - # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). - privileged: false - # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway). - options: - # The parent directory of a job's working directory. - # NOTE: There is no need to add the first '/' of the path as act_runner will add it automatically. - # If the path starts with '/', the '/' will be trimmed. - # For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir - # If it's empty, /workspace will be used. - workdir_parent: - # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob - # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted. - # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to: - # valid_volumes: - # - data - # - /src/*.json - # If you want to allow any volume, please use the following configuration: - # valid_volumes: - # - '**' - valid_volumes: [] - # overrides the docker client host with the specified one. - # If it's empty, act_runner will find an available docker host automatically. - # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. - # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work. - docker_host: "" - # Pull docker image(s) even if already present - force_pull: true - # Rebuild docker image(s) even if already present - force_rebuild: false - -host: - # The parent directory of a job's working directory. - # If it's empty, $HOME/.cache/act/ will be used. - workdir_parent: -EOF -} + user_data = templatefile("${path.module}/templates/user-data.sh.tftpl", { + docker = { version = var.docker_version, image = var.image }, + app_ini = local.app_ini_config, + user = { name = var.username, password = var.password, email = var.email }, + ports = { ssh = var.ssh_port, external = var.external_port, token = var.token_port }, + runner = { + create = var.create_runner, + image = var.runner_image, + binary_url = var.runner_binary_url, + config = local.runner_config, + }, + }) + app_ini_config = templatefile("${path.module}/templates/app.ini.tftpl", { + ports = { ssh = var.ssh_port, external = var.external_port }, + }) + runner_config = templatefile("${path.module}/templates/runner-config.yaml.tftpl", { + image = var.runner_image + }) +} \ No newline at end of file diff --git a/main.tf b/main.tf index eab5dbd..97351af 100644 --- a/main.tf +++ b/main.tf @@ -1,7 +1,7 @@ resource "aws_vpc_security_group_ingress_rule" "web" { security_group_id = var.security_group_id from_port = var.external_port - to_port = var.external_port + to_port = var.token_port ip_protocol = -1 cidr_ipv4 = "0.0.0.0/0" } @@ -20,8 +20,11 @@ resource "aws_iam_role" "gitea" { } ] }) +} - managed_policy_arns = var.gitea_role_managed_policies +resource "aws_iam_role_policy_attachments_exclusive" "gitea" { + role_name = aws_iam_role.gitea.name + policy_arns = var.gitea_role_managed_policies } resource "aws_iam_instance_profile" "gitea" { @@ -50,6 +53,7 @@ resource "aws_instance" "gitea" { } provisioner "local-exec" { - command = "until curl -s http://${self.public_ip}:${var.external_port}/api/healthz; do sleep 5; done" + #command = "until curl -s http://${self.public_ip}:${var.external_port}/api/healthz; do sleep 5; done" + command = "until curl -s http://${self.public_ip}:${var.external_port}/api/v1/users/${var.username}; do sleep 5; done" } } diff --git a/outputs.tf b/outputs.tf index 2709fce..05a98e9 100644 --- a/outputs.tf +++ b/outputs.tf @@ -2,10 +2,6 @@ output "base_url" { value = "http://${aws_instance.gitea.public_ip}:${var.external_port}/" } -output "empty_repo_url" { - value = "http://${aws_instance.gitea.public_ip}:${var.external_port}/${var.username}/${var.empty_repo_name}.git" -} - output "login_url" { value = "http://${aws_instance.gitea.public_ip}:${var.external_port}/user/login" } @@ -32,13 +28,9 @@ output "server_ip" { } output "role_arn" { - value = aws_iam_role.gitea.arn -} - -output "cloned_repo_url" { - value = "http://${aws_instance.gitea.public_ip}:${var.external_port}/${var.username}/${basename(var.cloned_repo_source)}.git" + value = aws_iam_role.gitea.arn } -output "cloned_repo_name" { - value = trimsuffix(basename(var.cloned_repo_source), ".git") +output "auth_token" { + value = data.http.auth_token.response_body } diff --git a/templates/app.ini.tftpl b/templates/app.ini.tftpl new file mode 100644 index 0000000..8cdb643 --- /dev/null +++ b/templates/app.ini.tftpl @@ -0,0 +1,106 @@ +APP_NAME = Gitea: Git with a cup of tea +RUN_MODE = prod +RUN_USER = git +WORK_PATH = /data/gitea + +[repository] +ROOT = /data/git/repositories +DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions + +[repository.local] +LOCAL_COPY_PATH = /data/gitea/tmp/local-repo + +[repository.upload] +TEMP_PATH = /data/gitea/uploads + +[server] +APP_DATA_PATH = /data/gitea +DOMAIN = PUBLIC_IP +SSH_DOMAIN = PUBLIC_IP +HTTP_PORT = ${ports.external} +ROOT_URL = http://PUBLIC_IP:${ports.external}/ +DISABLE_SSH = false +SSH_PORT = ${ports.ssh} +SSH_LISTEN_PORT = 22 +LFS_START_SERVER = true +LFS_JWT_SECRET = xqrgNapz38Zox2rfmA32TTdW5Ge1WIgsPUXsykJMIiw +OFFLINE_MODE = false + +[database] +PATH = /data/gitea/gitea.db +DB_TYPE = sqlite3 +HOST = localhost:3306 +NAME = gitea +USER = root +PASSWD = +LOG_SQL = false +SCHEMA = +SSL_MODE = disable + +[indexer] +ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve + +[session] +PROVIDER_CONFIG = /data/gitea/sessions +PROVIDER = file + +[picture] +AVATAR_UPLOAD_PATH = /data/gitea/avatars +REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars + +[attachment] +PATH = /data/gitea/attachments + +[log] +MODE = console +LEVEL = info +ROOT_PATH = /data/gitea/log + +[security] +INSTALL_LOCK = true +SECRET_KEY = +REVERSE_PROXY_LIMIT = 1 +REVERSE_PROXY_TRUSTED_PROXIES = * +INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MTQ5NTYwMTR9.7acb0biC_w1kt80Wd_DimlubtK9PfAOqk542r55JeXA +PASSWORD_HASH_ALGO = pbkdf2 + +[service] +DISABLE_REGISTRATION = false +REQUIRE_SIGNIN_VIEW = false +REGISTER_EMAIL_CONFIRM = false +ENABLE_NOTIFY_MAIL = false +ALLOW_ONLY_EXTERNAL_REGISTRATION = false +ENABLE_CAPTCHA = false +DEFAULT_KEEP_EMAIL_PRIVATE = false +DEFAULT_ALLOW_CREATE_ORGANIZATION = true +DEFAULT_ENABLE_TIMETRACKING = true +NO_REPLY_ADDRESS = noreply.localhost +ENABLE_BASIC_AUTHENTICATION = true + +[lfs] +PATH = /data/git/lfs + +[mailer] +ENABLED = false + +[openid] +ENABLE_OPENID_SIGNIN = true +ENABLE_OPENID_SIGNUP = true + +[cron.update_checker] +ENABLED = false + +[repository.pull-request] +DEFAULT_MERGE_STYLE = merge + +[repository.signing] +DEFAULT_TRUST_MODEL = committer + +[oauth2] +JWT_SECRET = kU9i_JAtfZ0z9yqnBks3ZQfjT0GAjU81zQz1sH6lraQ + +[actions] +ENABLED=true + +[metrics] +ENABLED=true \ No newline at end of file diff --git a/templates/runner-config.yaml.tftpl b/templates/runner-config.yaml.tftpl new file mode 100644 index 0000000..f40eb17 --- /dev/null +++ b/templates/runner-config.yaml.tftpl @@ -0,0 +1,96 @@ +# Example configuration file, it's safe to copy this as the default config file without any modification. + +# You don't have to copy this file to your instance, +# just run `./act_runner generate-config > config.yaml` to generate a config file. + +log: + # The level of logging, can be trace, debug, info, warn, error, fatal + level: info + +runner: + # Where to store the registration result. + file: .runner + # Execute how many tasks concurrently at the same time. + capacity: 1 + # Extra environment variables to run jobs. + envs: + A_TEST_ENV_NAME_1: a_test_env_value_1 + A_TEST_ENV_NAME_2: a_test_env_value_2 + # Extra environment variables to run jobs from a file. + # It will be ignored if it's empty or the file doesn't exist. + env_file: .env + # The timeout for a job to be finished. + # Please note that the Gitea instance also has a timeout (3h by default) for the job. + # So the job could be stopped by the Gitea instance if it's timeout is shorter than this. + timeout: 3h + # Whether skip verifying the TLS certificate of the Gitea instance. + insecure: false + # The timeout for fetching the job from the Gitea instance. + fetch_timeout: 5s + # The interval for fetching the job from the Gitea instance. + fetch_interval: 2s + # The labels of a runner are used to determine which jobs the runner can run, and how to run them. + # Like: "macos-arm64:host" or "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest" + # Find more images provided by Gitea at https://gitea.com/gitea/runner-images . + # If it's empty when registering, it will ask for inputting labels. + # If it's empty when execute `daemon`, will use labels in `.runner` file. + labels: + - "ubuntu-latest:docker://${image}" + +cache: + # Enable cache server to use actions/cache. + enabled: true + # The directory to store the cache data. + # If it's empty, the cache data will be stored in $HOME/.cache/actcache. + dir: "" + # The host of the cache server. + # It's not for the address to listen, but the address to connect from job containers. + # So 0.0.0.0 is a bad choice, leave it empty to detect automatically. + host: "" + # The port of the cache server. + # 0 means to use a random available port. + port: 0 + # The external cache server URL. Valid only when enable is true. + # If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself. + # The URL should generally end with "/". + external_server: "" + +container: + # Specifies the network to which the container will connect. + # Could be host, bridge or the name of a custom network. + # If it's empty, act_runner will create a network automatically. + network: "" + # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). + privileged: false + # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway). + options: + # The parent directory of a job's working directory. + # NOTE: There is no need to add the first '/' of the path as act_runner will add it automatically. + # If the path starts with '/', the '/' will be trimmed. + # For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir + # If it's empty, /workspace will be used. + workdir_parent: + # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob + # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted. + # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to: + # valid_volumes: + # - data + # - /src/*.json + # If you want to allow any volume, please use the following configuration: + # valid_volumes: + # - '**' + valid_volumes: [] + # overrides the docker client host with the specified one. + # If it's empty, act_runner will find an available docker host automatically. + # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. + # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work. + docker_host: "" + # Pull docker image(s) even if already present + force_pull: true + # Rebuild docker image(s) even if already present + force_rebuild: false + +host: + # The parent directory of a job's working directory. + # If it's empty, $HOME/.cache/act/ will be used. + workdir_parent: \ No newline at end of file diff --git a/templates/user-data.sh.tftpl b/templates/user-data.sh.tftpl new file mode 100644 index 0000000..c47bdd6 --- /dev/null +++ b/templates/user-data.sh.tftpl @@ -0,0 +1,77 @@ +#!/bin/bash + +set -x + +touch /home/ec2-user/.user-data-started + +echo --- install docker --- +dnf update -y +dnf install -y nmap-ncat python3-pip python3 tmux htop git jq aws awk # TODO probably only need git +dnf install -y ${docker.version} +systemctl enable docker +systemctl start docker +newgrp + +echo --- setup gitea --- +docker pull -q ${docker.image} +mkdir /etc/gitea /data +mkdir -vp /etc/gitea/gitea/conf/ +cat < /etc/gitea/gitea/conf/app.ini +${app_ini} +EOT +PUBLIC_IP=$(curl -s http://checkip.amazonaws.com) +sed -i s/PUBLIC_IP/$PUBLIC_IP/g /etc/gitea/gitea/conf/app.ini + +echo --- start gitea --- +docker network create gitea +docker run -d \ + --name gitea \ + --network gitea \ + --restart always \ + -e USER_UID=1000 \ + -e USER_GID=1000 \ + -v /etc/gitea:/data \ + -v /etc/timezone:/etc/timezone:ro \ + -v /etc/localtime:/etc/localtime:ro \ + -p ${ports.external}:3000 \ + -p ${ports.ssh}:22 \ + ${docker.image} + +while [ "$(curl -s http://localhost:${ports.external}/api/healthz | jq -r .status)" != "pass" ]; do sleep 2; done && echo "pass" + +echo ---create user --- +docker exec -u git gitea bash -c "/app/gitea/gitea migrate" +docker exec -u git gitea bash -c \ + "/app/gitea/gitea admin user create --username ${user.name} --email ${user.email} --password ${user.password} --admin" + +echo --- create token --- +mkdir -vp /token +docker exec -u git gitea bash -c \ + "/app/gitea/gitea admin user generate-access-token --username ${user.name} --token-name ${user.name} --scopes all" | awk '{print $NF}' | xargs echo -n > /token/token +cd /token +nohup python3 -m http.server ${ports.token} & +cd - + +if [ "${runner.create}" = true ]; then + echo --- pull runner image --- + docker pull -q ${runner.image} & + + echo --- install runner --- + curl -sL ${runner.binary_url} > /usr/local/bin/act + chmod +x /usr/local/bin/act + + echo --- create runner config --- + cat < ./runner.yaml + ${runner.config} +EOC + + echo --- register runner --- + RUNNER_TOKEN=$(docker exec -u git gitea bash -c "/app/gitea/gitea actions generate-runner-token") + act register --no-interactive --instance http://$PUBLIC_IP:${ports.external} --token "$RUNNER_TOKEN" + + echo --- start runner --- + nohup act --config ./runner.yaml daemon & +fi + +echo --- gitea setup finished --- +touch /home/ec2-user/.gitea-ready \ No newline at end of file diff --git a/variables.tf b/variables.tf index 4bb7731..22388b6 100644 --- a/variables.tf +++ b/variables.tf @@ -4,12 +4,6 @@ variable "instance_type" { default = "t2.micro" } -variable "runner_instance_type" { - description = "Runner EC2 instance type" - type = string - default = "t2.micro" -} - variable "instance_name" { description = "EC2 instance name" type = string @@ -19,7 +13,7 @@ variable "instance_name" { variable "image" { description = "Gitea docker image" type = string - default = "public.ecr.aws/cloudacademy-labs/cloudacademy/labs/gitea:1.22.1-57a63cf" + default = "public.ecr.aws/cloudacademy-labs/cloudacademy/labs/gitea:1.22.3-de167e2" } variable "username" { @@ -40,24 +34,6 @@ variable "email" { default = "student@cloudacademylabs.com" } -variable "create_empty_repo" { - description = "Create an empty repository" - type = bool - default = false -} - -variable "empty_repo_name" { - description = "Gitea repository name" - type = string - default = "lab-repo" -} - -variable "empty_repo_description" { - description = "Gitea repository description" - type = string - default = "Lab Repository" -} - variable "external_port" { description = "Gitea external port" type = number @@ -70,10 +46,10 @@ variable "ssh_port" { default = 222 } -variable "jwt_secret" { - description = "JWT secret" - type = string - default = "kU9i_JAtfZ0z9yqnBks3ZQfjT0GAjU81zQz1sH6lraQ" +variable "token_port" { + description = "Gitea token port" + type = number + default = 3001 } variable "key_pair_name" { @@ -92,18 +68,6 @@ variable "volume_size" { default = 50 } -variable "create_cloned_repo" { - description = "Create a cloned repository" - type = bool - default = false -} - -variable "cloned_repo_source" { - description = "Command to clone the repository" - type = string - default = "https://github.com/cloudacademy/python-flask-microservices.git" -} - variable "docker_version" { description = "Docker version in the DNF repository" type = string @@ -128,24 +92,6 @@ variable "gitea_role_managed_policies" { default = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"] } -variable "create_secret" { - description = "Create a secret" - type = bool - default = false -} - -variable "secret_name" { - description = "Secret name" - type = string - default = "GITEACREDS" -} - -variable "secret_value" { - description = "Secret value" - type = string - default = "student:LabPassword123" -} - variable "create_runner" { description = "Create a runner" type = bool From 0d260f93313d12a7930836d2501d9726ec2bba49 Mon Sep 17 00:00:00 2001 From: Andrew Burchill Date: Tue, 22 Oct 2024 14:40:56 +1100 Subject: [PATCH 2/2] Wait for token to be available --- main.tf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 97351af..7fb93d0 100644 --- a/main.tf +++ b/main.tf @@ -53,7 +53,6 @@ resource "aws_instance" "gitea" { } provisioner "local-exec" { - #command = "until curl -s http://${self.public_ip}:${var.external_port}/api/healthz; do sleep 5; done" - command = "until curl -s http://${self.public_ip}:${var.external_port}/api/v1/users/${var.username}; do sleep 5; done" + command = "until curl -s http://${self.public_ip}:${var.token_port}/token; do sleep 5; done" } }