diff options
-rw-r--r-- | utils/mod.ts | 1 | ||||
-rw-r--r-- | utils/prepend.ts | 4 | ||||
-rw-r--r-- | worker/Dockerfile | 15 | ||||
-rw-r--r-- | worker/scripts/ansible_playbook | 76 |
4 files changed, 44 insertions, 52 deletions
diff --git a/utils/mod.ts b/utils/mod.ts index 93457f0..8c5dc45 100644 --- a/utils/mod.ts +++ b/utils/mod.ts @@ -2,3 +2,4 @@ export * from "./env.ts"; export * from "./run.ts"; export * from "./secret.ts"; export * from "./validate_identifier.ts"; +export * from "./prepend.ts"; diff --git a/utils/prepend.ts b/utils/prepend.ts new file mode 100644 index 0000000..9b77aff --- /dev/null +++ b/utils/prepend.ts @@ -0,0 +1,4 @@ +export const prependWith = (arr: string[], prep: string) => + Array(arr.length * 2).fill(0) + .map((_, i) => i % 2 === 0) + .map((isPrep, i) => isPrep ? prep : arr[i]); diff --git a/worker/Dockerfile b/worker/Dockerfile index 9597f83..563908b 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -1,4 +1,11 @@ -FROM oci.liz.coffee/img/liz-ci:release as worker +FROM oci.liz.coffee/img/liz-ci:release AS worker + +# Image building / publishing jobs +RUN apt-get install -yqq ca-certificates curl +RUN curl "https://get.docker.com/builds/`uname -s`/`uname -m`/docker-latest.tgz" > docker.tgz &&\ + tar -xvzf docker.tgz &&\ + mv docker/* /usr/local/bin &&\ + rm -rf docke* RUN groupadd docker RUN useradd --system --home-dir /var/lib/laminar \ @@ -11,12 +18,6 @@ RUN unzip /tmp/bw-linux.zip RUN mv bw /usr/local/bin RUN rm /tmp/bw-linux.zip -# Image building / publishing jobs -RUN apt install -yqq docker-ce-cli - -# Ansible playbooks -RUN apt install -yqq ansible-core openssh-client - USER laminar WORKDIR /var/lib/laminar EXPOSE 8080 diff --git a/worker/scripts/ansible_playbook b/worker/scripts/ansible_playbook index bfeeb8b..a85995b 100644 --- a/worker/scripts/ansible_playbook +++ b/worker/scripts/ansible_playbook @@ -4,6 +4,7 @@ import { BitwardenSession, getRequiredEnv, getStdout, + prependWith, type SecureNote, } from "@liz-ci/utils"; import type { AnsiblePlaybookJobProps } from "@liz-ci/model"; @@ -13,55 +14,40 @@ const args: AnsiblePlaybookJobProps = { playbooks: getRequiredEnv("playbooks"), }; -const tempKeyFile = await Deno.makeTempFile(); -const cwd = Deno.cwd(); const bitwardenSession = new BitwardenSession(); +const secretFiles = await Promise.all( + ["ansible_secrets", "ssh_key"] + .map((secretName) => + bitwardenSession + .getItem<SecureNote>(secretName) + .then(async ({ notes: recoveredSecret }) => { + const tempFile = await Deno.makeTempFile(); + await Deno.writeTextFile(tempFile, recoveredSecret); + return tempFile; + }) + ), +); +const [ansibleSecrets, sshKey] = secretFiles; try { - Deno.chdir(args.path); + const volumes = [ + `${args.path}:/ansible`, + `${sshKey}:/root/id_rsa`, + `${ansibleSecrets}:/ansible/secrets.yml`, + ]; + const playbookCmd = `ansible-playbook -e @secrets.yml ${args.playbooks}`; - const { notes: ansibleSecrets } = await bitwardenSession.getItem<SecureNote>( - "ansible_secrets", - ); - await Deno.writeTextFile("secrets.yml", ansibleSecrets); - - const { notes: privateKey } = await bitwardenSession.getItem<SecureNote>( - "ssh_key", - ); - - // Create a temporary file for the SSH key - await Deno.writeTextFile(tempKeyFile, privateKey); - await getStdout(["chmod", "600", tempKeyFile]); - - // Start ssh-agent and add the key - const sshAgent = await getStdout(["ssh-agent", "-s"]); - const [SSH_AGENT_PID, SSH_AUTH_SOCK] = [ - /SSH_AGENT_PID=(\d+)/, - /SSH_AUTH_SOCK=([^;]+)/, - ] - .map((regex) => sshAgent.match(regex)?.[1]) - .map((val) => { - if (!val) throw new Error("Failed to start ssh-agent"); - return val; - }); - - const sshEnv = { - SSH_AGENT_PID, - SSH_AUTH_SOCK, - }; - await getStdout(["ssh-add", tempKeyFile], { - env: sshEnv, - }); await getStdout([ - "ansible-playbook", - "-e", - "@secrets.yml", - ...args.playbooks.split(" "), - ], { env: sshEnv }); -} finally { - await Promise.allSettled([ - Deno.chdir.bind(null, cwd), - Deno.remove(tempKeyFile), - getStdout(["ssh-agent", "-k"]), + "docker", + "run", + ...prependWith(volumes, "-v"), + "willhallonline/ansible:latest", + ...playbookCmd.split(" "), ]); +} finally { + await Promise.allSettled( + [bitwardenSession.close()].concat( + secretFiles.map((p) => Deno.remove(p)), + ), + ); } |