diff --git a/Taskfile.yml b/Taskfile.yml index 5c4675a..6bfa648 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -11,6 +11,7 @@ tasks: deploy: ansible-playbook playbooks/deploy.yml {{.CLI_ARGS}} destroy: ansible-playbook playbooks/destroy.yml {{.CLI_ARGS}} restore: ansible-playbook playbooks/restore.yml {{.CLI_ARGS}} + runner: ansible-playbook playbooks/runner.yml {{.CLI_ARGS}} assets: - cp ./assets/icon.png ./gitea/custom/public/assets/img/logo.png @@ -25,3 +26,10 @@ tasks: vars: KEY: { sh: ansible-vault view vault.yml | yq -r ".secret.private_ssh_key_path" } IP: { sh: cat dist/terraform_outputs.yml | jq -r ".server_ip.value" } + + enter-runner: + cmd: ssh -i {{.KEY}} -o ProxyCommand="ssh -i {{.KEY}} -p 2222 -W %h:%p root@{{.IP}}" root@{{.RUNNER_IP}} + vars: + KEY: { sh: ansible-vault view vault.yml | yq -r ".secret.private_ssh_key_path" } + IP: { sh: cat dist/terraform_outputs.yml | jq -r ".server_ip.value" } + RUNNER_IP: { sh: cat dist/terraform_outputs.yml | jq -r ".runner_ip.value" } diff --git a/gitea/config/app.ini b/gitea/config/app.ini index 9648ad6..2031c78 100644 --- a/gitea/config/app.ini +++ b/gitea/config/app.ini @@ -91,6 +91,9 @@ DEFAULT_MERGE_STYLE = merge [repository.signing] DEFAULT_TRUST_MODEL = committer +[actions] +ENABLED = true + [storage] STORAGE_TYPE = minio MINIO_USE_SSL = true diff --git a/gitea/config/dev.app.ini b/gitea/config/dev.app.ini index 1f1b906..a51ae69 100644 --- a/gitea/config/dev.app.ini +++ b/gitea/config/dev.app.ini @@ -96,6 +96,9 @@ DEFAULT_TRUST_MODEL = committer [oauth2] JWT_SECRET = x-----------------------------------------x +[actions] +ENABLED = true + [storage] STORAGE_TYPE = minio MINIO_ENDPOINT = localstack:4566 diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml index 4f9eb35..8ba7f6c 100644 --- a/playbooks/deploy.yml +++ b/playbooks/deploy.yml @@ -108,6 +108,41 @@ - docker-buildx-plugin - docker-compose-plugin +- name: Enable NAT for private network. + hosts: server + gather_facts: false + tasks: + - name: Enable IP forwarding. + ansible.posix.sysctl: + name: net.ipv4.ip_forward + value: "1" + sysctl_set: true + reload: true + + - name: Add NAT masquerade rule. + ansible.builtin.iptables: + table: nat + chain: POSTROUTING + source: "10.0.1.0/24" + jump: MASQUERADE + state: present + + - name: Allow forwarding from private network. + ansible.builtin.iptables: + chain: DOCKER-USER + source: "10.0.1.0/24" + jump: ACCEPT + action: insert + state: present + + - name: Allow established/related return traffic. + ansible.builtin.iptables: + chain: DOCKER-USER + ctstate: ESTABLISHED,RELATED + jump: ACCEPT + action: insert + state: present + - name: Deploy artifact to instance. hosts: server tags: diff --git a/playbooks/runner.yml b/playbooks/runner.yml new file mode 100644 index 0000000..64dafa4 --- /dev/null +++ b/playbooks/runner.yml @@ -0,0 +1,131 @@ +- name: Set up runner host via jumphost. + gather_facts: false + hosts: localhost + vars_files: + - ../vault.yml + - ../dist/terraform_outputs.yml + tasks: + - name: Add gitea server as jumphost. + ansible.builtin.add_host: + name: server + ansible_ssh_host: "{{ server_ip.value }}" + ansible_user: root + ansible_port: 2222 + ansible_private_key_file: "{{ secret.private_ssh_key_path }}" + + - name: Add runner host (via jumphost). + ansible.builtin.add_host: + name: runner + ansible_ssh_host: "{{ runner_ip.value }}" + ansible_user: root + ansible_private_key_file: "{{ secret.private_ssh_key_path }}" + ansible_ssh_common_args: >- + -o ProxyCommand="ssh -i {{ secret.private_ssh_key_path }} -p 2222 -W %h:%p root@{{ server_ip.value }}" + +- name: Install Docker on runner. + gather_facts: true + hosts: runner + vars_files: + - ../vault.yml + - ../dist/terraform_outputs.yml + tasks: + - name: Set DNS resolver. + ansible.builtin.copy: + content: "nameserver 185.12.64.2\n" + dest: /etc/resolv.conf + mode: "0644" + + - name: Install PIP. + ansible.builtin.apt: + state: present + update_cache: true + name: + - python3-pip + + - name: Install needed packages. + ansible.builtin.pip: + name: + - packaging + state: present + break_system_packages: true + + - name: Download Docker repository key. + ansible.builtin.apt_key: + url: https://download.docker.com/linux/debian/gpg + state: present + + - name: Download Docker repository. + ansible.builtin.apt_repository: + repo: "deb https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable" + state: present + + - name: Remove bad packages. + ansible.builtin.apt: + state: absent + package: + - docker.io + - docker-doc + - docker-compose + - podman-docker + - containerd + - runc + + - name: Download Docker dependencies. + ansible.builtin.apt: + state: present + package: + - ca-certificates + - curl + - jq + + - name: Download Docker packages. + ansible.builtin.apt: + state: present + update_cache: true + package: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + +- name: Register and start Gitea runner. + hosts: runner + gather_facts: false + vars_files: + - ../vault.yml + - ../dist/terraform_outputs.yml + vars: + gitea_internal_url: "https://{{ server_fqdn.value }}" + tasks: + - name: Create runner data volume. + community.docker.docker_volume: + name: runner-data + state: present + + - name: Generate runner config. + ansible.builtin.copy: + dest: /root/runner-config.yaml + mode: "0644" + content: | + runner: + insecure: true + + - name: Start Gitea runner container. + community.docker.docker_container: + name: gitea-runner + image: gitea/act_runner:latest + state: started + recreate: true + restart_policy: unless-stopped + etc_hosts: + "{{ server_fqdn.value }}": "10.0.1.2" + volumes: + - runner-data:/data + - /var/run/docker.sock:/var/run/docker.sock + - /root/runner-config.yaml:/config.yaml:ro + env: + GITEA_INSTANCE_URL: "{{ gitea_internal_url }}" + GITEA_RUNNER_REGISTRATION_TOKEN: "{{ secret.runner_registration_token }}" + GITEA_RUNNER_NAME: "runner-01" + CONFIG_FILE: "/config.yaml" diff --git a/terraform/main.tf b/terraform/main.tf index 4f4543f..bcf73ca 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -60,3 +60,23 @@ resource "hcloud_firewall_attachment" "server_fw_attachment" { firewall_id = hcloud_firewall.server_firewall.id server_ids = [hcloud_server.server_instance.id] } + +resource "hcloud_server" "runner_instance" { + name = "runner-server" + image = local.server_image + server_type = local.server_type + datacenter = local.datacenter + ssh_keys = [hcloud_ssh_key.ssh_key.id] + + public_net { + ipv4_enabled = false + ipv6_enabled = false + } + + network { + network_id = hcloud_network.private_network.id + ip = local.runner_ip + } + + depends_on = [hcloud_network_subnet.private_subnet] +} diff --git a/terraform/network.tf b/terraform/network.tf new file mode 100644 index 0000000..07ac3dc --- /dev/null +++ b/terraform/network.tf @@ -0,0 +1,24 @@ +resource "hcloud_network" "private_network" { + name = "repository-network" + ip_range = local.network_cidr +} + +resource "hcloud_network_subnet" "private_subnet" { + network_id = hcloud_network.private_network.id + type = "cloud" + network_zone = local.network_zone + ip_range = local.subnet_cidr +} + +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server_instance.id + network_id = hcloud_network.private_network.id + ip = local.server_ip +} + +resource "hcloud_network_route" "nat_route" { + network_id = hcloud_network.private_network.id + destination = "0.0.0.0/0" + gateway = local.server_ip +} + diff --git a/terraform/outputs.tf b/terraform/outputs.tf index f2e54d1..701e6d2 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -1,11 +1,17 @@ output "server_ip" { description = "The public address of the server." - value = hcloud_server.server_instance.ipv4_address - sensitive = false + value = hcloud_server.server_instance.ipv4_address + sensitive = false } output "server_fqdn" { description = "The public domain of the server." - value = "${local.subdomain}.${local.domain}" - sensitive = false + value = "${local.subdomain}.${local.domain}" + sensitive = false +} + +output "runner_ip" { + description = "The private network address of the runner." + value = local.runner_ip + sensitive = false } diff --git a/terraform/variables.tf b/terraform/variables.tf index 2c72936..f844ce1 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -5,6 +5,12 @@ locals { domain = "maximhutz.com" subdomain = "git" + + network_zone = "eu-central" + network_cidr = "10.0.0.0/16" + subnet_cidr = "10.0.1.0/24" + server_ip = "10.0.1.2" + runner_ip = "10.0.1.3" } # ---------------------------------------------------------------------------- # diff --git a/vault.yml b/vault.yml index 0270f76..6212224 100644 --- a/vault.yml +++ b/vault.yml @@ -1,70 +1,73 @@ $ANSIBLE_VAULT;1.1;AES256 -62353135613131656461393763316639363866326663633830306532306430373638396437373064 -6365353865303534366432616235373930616665306666660a396332353639633164366562666461 -34393030333732326436386234626532373939613435656161306131626634313730666532386362 -6130323636623233390a303631366464636561623133343334393865646639643030323732653834 -39366539663463386236303531326437396439636362306639306230356265373936636132633334 -62376235353261626665666161393232623564646633633538613963356565323536303137393633 -31333763303163396530623939336165346433643562636566353238393265623538346563313164 -37303230336261306365613132626132333463323261386536313765393164346364643036646263 -39353131333561646538336130663337646139663362666332373736366236643436666265613930 -38623634366665353039336330633235393039373839663938386366383834373238343237653362 -66303763396463373139646638333662346538333662363234616466343634643034636363343539 -31393464323463326632373438346336366434323664303230616630623636323164336162323534 -39376363616361636164653030316464356438313331333962626330636232363065663764613930 -32373262326166633536656366323637326333346233663938633530363632353539363331376636 -32383636616262303364633039666163363932643766363934333931616663353665353237363030 -62366634343461396539633537646564343237613661373835613534396439386437616264636164 -38653930386635613465616137356536316534393030396366323633346539323638373166633633 -34393866396263386535633435306232323331353263373530323837303237623939616532366463 -65366432313438333333636631623339316162623139323631626336343465646330356232313238 -36313266363162626330323033333430363964353236343032643839643530333235633738616365 -62653763323365353334646638616434366138346165623866323762613435333436366163666633 -34643839613934366636353839363433396332343564633663353735333731333065346432363663 -37373964323461623033383635376333316238336638653362656631393561366661643934316565 -63356634313161373037353164336665333039666230643934363064393039616438323832356265 -30313966313065626335656433326237656134396264383066653730643136636363353965313966 -62663631306561373337653661663965636335363766383266363133636438346464613731363961 -65346162376164646334356431386561656262366139613664643132363636346339376539303739 -37383764656562636364326464613037383939346333396164356139393230376566653435653636 -36383266323561363763633236326266623561613735616439366162393031376665376232646238 -30646434363839663432613766343935306561636366303865623537313732376639666533353536 -37373765376236396662306463343261353031353839616363373036376562333633336236383036 -35653865363561623839616264326563626362623839373438363065333531373965656632303135 -32303933353066303039636232626433343139353963613162326431346363336137303564616339 -61366461326539376165646262393830623662613938303534633837346563626639356164613838 -37613963366433346563346661666334346231346530623238646161316631636339396436616565 -30363532623465386631623161396462346166323161306436373965633961386266636539333864 -31373437356434353362633562363630663462626162613430393563393665336436626238326362 -63646537663039646266623338333734666665656431633464343863373563393836333964633437 -33303430643935373930343835376335626338633431653365366137373131316661666663643538 -65366563313433303234353032396166616630633137643763643036626261663231303361313365 -62626135376434326266653538623063383335383635316339623864356533306364336131336138 -38373831386633336235336530343561333966636263303732356433333839663161633634386662 -62306336666636636362663934383863313930656564336437643833346263343464323334613032 -34363461613566393131643661363763646236326562336236363066326266336637313338643336 -31393233623738616566373838366434346131663063653931336563633565663065306139306436 -64633963393232363164613962623434626632373366356133323665666561386230326335633637 -33663135396632616563663538313533623866336162303961663231333033633133376361306664 -64313939306566366538373861613538663232383539313433613232363133343234656331663134 -64626262373433343138393961613162373063346562626232316231316536356632386466373835 -38303365376230653734366434383263616533343233393362306635666265636531363965373563 -31623562636239666334393765396238316239613562626136336466333239396165383832656362 -61623565306139616333346139363464663335663930623237313438366130316530383634623832 -30656339353736373364393664663266633961323861313061656661643564303439393831326566 -63333261393135323437663337353866396563313363313465653063316632626666323338643331 -35323930613763663462303532626532353435313235623631613239353266306239323864363863 -32636335643738643738653438323236646366623637303839313365633763646434613662626237 -30656630656638323362636537633662323230353865656665663334336138316365366361643862 -39623336346430656335663630303232396638656164613436346237653939393264626336333664 -37333739303932366165326633313835343762613539613066336662376634326265366666306264 -65633839363730626363663061356362623062623166356664333733633164643364323234393630 -36326337376164393265356137653634656634313836663430323139613461303165336438336230 -65636639326236366539343537356263343637393165323139316632646636386333366261646535 -31613635373965343563373739643937633538336638303231316336386335366466363163643834 -64303235666636396633613665626335346563663034336365326563383765646639643462653762 -37306639613137383165613563616238653837616561623339356338616233386535353830623931 -65623236643963396232373938353264633334326133656238343735653164323239396435313037 -61643631663330396363356632316266303031346332386337353464393832643636396339346333 -31393238356637373361653262666462633831316632323633383134663763313362376639376431 -6237 +30646630636633336635633463343933323930346431663331313133343737326566643031363961 +3963373966333330363032346563306363373132643738330a636261613164336537643463663165 +36363234643564316331363438313032363961353630623033303735353439346331333138633937 +6331613661656534380a326162643030623164616437626635393933353931366130653535353764 +35306463323533376465623734336534326233363737643661633463626532306161353166313833 +61646235666166366330303737613332653466353737626663616531323136353738613537356163 +37646262363264316630666633636365316634643435636132643865393038623039663333316435 +38666166633366643264306563633039643761623237316439333838313836336437386462353630 +36323538613239393938313564643637343930376535363630643635343037383737386630343531 +39626138623930663835366130343537356136333530316566623530623030346664326663343464 +30393031343638613436626265616632323264663435653533376535396266323331626162326131 +37343031373839316135623363386133653231633965653663653366643630366366343431626530 +66316337646665303339323736373834366634376533306334323337356261343038373037623134 +32336266656137623266616564633238303565363933623465386134303537646563613135643836 +62643233646535363237363063326535636232376361366539633136333031663761653535613266 +30353738303661333434653034373961666665343739343264396135633763343637393839353465 +31373666626662616536663963396662303937303034653164306138336431303735383436346166 +32376562613438646166653637663064313435366563313563666564326662663834613435636133 +38396334393836346263663061333537303533633733636639646330393638303237613466643731 +37653065346263643264663230383435323334616432383531333563336235346535356338363632 +32666361396233623539333934616361643937396165636134646666363563363263383262633831 +63383837383039346664663334613832343662633331626463613830383863343332316530656331 +31343331623462323437643834663934386434626436366239323065343638396239383338636136 +61306236623036376664336563626564623132363366646162376464626162633037653466336462 +65636233623032636137316235613062393465646532353232393038316238636366313638343033 +30653263356366636331653964336138613462383339626564636434613832343934343138386536 +38396161666164306430326533323964373664333830386534613461393361346262333337663563 +33663633653032653538663930393938613931316537396466663933323231393037373632663637 +66626562623434393033373335633336316532366661393139356561323831623236353130313039 +39656262366566636136373863613464653661363634303036306462376431323163616535626561 +31663563616233393039326436356434663531346531643236333438346362363531396335313037 +64656432333634643438333236353235616565336662393761303835346538313136333634633939 +33303931616237646534663536353366383239643837653630353966346261303434343932316438 +33373530626562656339663530646632646331646538626435613863613064643633323139316232 +37623263643135383365356531616632393337643237313733383764313763323138643637613863 +61626237303062656166356537353364383865346331393564336530363066646636343236626130 +62393335313239373533373135366534363734623865363266623832626432626231383764643731 +63626333333836373964323334353562353366343265366338383665636133373366616137316431 +30633437363438663539393032396662356339666131656464323433656137396436373636646335 +30366431333932343561393361333032346535666163393563353761653163343631643436343930 +31666366346136616130393161663737666434633439323833326462623638306466396533353338 +32313966363532373933643461653135303339663362303030303065313239353939376661303630 +36666262636464316661323761653766306536663333316363363136326231333530396165363337 +31303864613630386561393837386533383138303763316563363230366630396437343665343138 +36323135386465306239633637626335316666396265393565643434656164393437653862386538 +31316236336130323436653836343232623762326263333234316530313763646633613739333834 +32656261336563383937353035383836373466616161373464356633333131623561386534343933 +65636232353636663131356661666536616438383631313766366263313235646137303131363435 +35396537363036353039646133306365376161326232373736626261383130346666346333313136 +33343762666431373935616361326461656463306661313239353066636635346263616431366538 +66613763633564363162316531633735626463626462353566356239353365663565616437326237 +61653962646532383232376330323662656532623334666233346531353936313236353938633735 +62343663356266353563643632393631366639633730666337616336663730643139323438313565 +30303631333835373061363935313965316663613131386437396633653630613865383062333564 +33343163313164373437633466393733663661646332636264323531386262613166633962303166 +31383139623834633636356137343464363436326631666638323463636531336337316664663131 +37623835356161346339663730623531336662326235633538353966343633393933336362333233 +38363163616666326638393764346665663462386139613635346433396337393962343837353031 +66343762653137363863326465613939646437616662386261626464663432626235613336323130 +33653238323662366335383362613130353238653964623861633630623061396338393838666362 +65623236366238373265363834643461633861303132333133663337333831333264613066393335 +33393362313465343364663234646561626166376262366332333439623134333266366331386666 +32353834313733646633663135633132623962643266346233353137353837396334393265373535 +64663036386331636134376362646361666532346637663131326539623364623632353165313266 +36326439663935643438356130366436633639636436363766376138343138353061663730663466 +62623463326664383961643965636133346538623332366138653262356439356462633435386238 +33316262353633353762326332313934356565623664396163306432383833356661643030376234 +63656361633939373565313932653963373038376166633636656638353961633664613338303237 +65303731393262613963623964386333396631626239316231313162323938316464343266653362 +32316636373265346339343938663137623664373432366364343133636430333736383932616562 +61663239383662646430303532623663303965353366303139646338643434666464626434663035 +30636162613464653332