import * as command from '@pulumi/command'; import * as digitalocean from '@pulumi/digitalocean'; import * as hcloud from '@pulumi/hcloud'; import * as pulumi from '@pulumi/pulumi'; import * as tls from '@pulumi/tls'; import * as fs from 'fs'; const config = new pulumi.Config(); const hcloudToken = config.getSecret('hcloudToken'); if (hcloudToken === undefined) { throw new Error('Hetzner Cloud token was not set'); } const provider = new hcloud.Provider('provider', { token: hcloudToken, }); const sshKey = new tls.PrivateKey('sshKey', { algorithm: 'ED25519', }); export const privateKey = sshKey.privateKeyOpenssh; privateKey.apply((privKey) => fs.writeFileSync('././local/private_key', privKey, { mode: '0600' }) ); const hetznerSshKey = new hcloud.SshKey( 'iac_default', { publicKey: sshKey.publicKeyOpenssh, }, { provider } ); export const swarmMaster = await createSwarmCluster(1); async function createSwarmCluster(nodeCount: number) { const dockerImage = await hcloud.getImage( { name: 'docker-ce', withArchitecture: 'x86', }, { provider } ); const swarmNet = new hcloud.Network( 'swarm-net', { ipRange: '172.16.0.0/16', }, { provider } ); const swarmSubNet = new hcloud.NetworkSubnet( 'swarm-subnet-dev', { networkId: swarmNet.id.apply((id) => +id), type: 'cloud', networkZone: 'eu-central', ipRange: '172.16.1.0/24', }, { provider } ); const vm = new hcloud.Server( `node-1`, { sshKeys: [hetznerSshKey.id], serverType: 'ccx23', location: 'fsn1', image: `${dockerImage.id}`, labels: { nodeType: 'dockerSwarmNode' }, }, { provider } ); const srvNet = new hcloud.ServerNetwork( 'node_1-net', { serverId: vm.id.apply((id) => +id), networkId: swarmNet.id.apply((id) => +id), ip: '172.16.1.1', }, { provider } ); const swarmInit = vm.id.apply((id) => { return new command.remote.Command( `dockerSwarmInit-${id}`, { connection: { host: vm.ipv4Address, user: 'root', privateKey: privateKey, }, create: [ 'docker swarm init --advertise-addr 172.16.1.1', 'echo "Manager Token: $(docker swarm join-token -q manager)"', 'echo "Worker Token: $(docker swarm join-token -q worker)"', ].join('&&'), }, { dependsOn: [vm] } ); }); const swarmTokens = { worker: '', manager: '', }; swarmInit.stdout.apply((output) => { const managerToken = output.match(/Manager Token: (\S+)/)?.[1]; const workerToken = output.match(/Worker Token: (\S+)/)?.[1]; if (managerToken && workerToken) { swarmTokens.manager = managerToken; swarmTokens.worker = workerToken; } }); // for (let i = 1; i < nodeCount; i++) { // const node = new hcloud.Server( // `node-${i + 1}`, // { // sshKeys: [hetznerSshKey.id], // serverType: 'cx21', // location: 'fsn1', // image: `${dockerImage.id}`, // labels: { nodeType: 'dockerSwarmNode' }, // userData: cloudConfig.then((cc) => cc.rendered), // }, // { provider, dependsOn: [swarmInit] } // ); // const srvNet = new hcloud.ServerNetwork( // `node_${i + 1}-net`, // { // serverId: node.id.apply((id) => +id), // networkId: swarmNet.id.apply((id) => +id), // ip: `172.16.1.${i + 1}`, // }, // { provider } // ); // const swarmJoin = node.id.apply((id) => { // return new command.remote.Command( // `dockerSwarmInit-${id}`, // { // connection: { // host: node.ipv4Address, // user: 'root', // privateKey: privateKey, // }, // create: vm.ipv4Address.apply( // (ip) => // `docker swarm join --token ${swarmTokens.worker} 172.16.1.1:2377` // ), // }, // { dependsOn: [node] } // ); // }); // } return vm; } const geniusceo = digitalocean.Domain.get( 'geniusceo', 'genius.ceo', ); const wwwSubDomain = geniusceo.id.apply( (id) => new digitalocean.DnsRecord('www', { domain: id, type: 'A', value: swarmMaster.ipv4Address, name: 'www', }) ); const noSubDomain = geniusceo.id.apply( (id) => new digitalocean.DnsRecord('noSub', { domain: id, type: 'A', value: swarmMaster.ipv4Address, name: '@', }) ); const wildcardSubDomain = geniusceo.id.apply( (id) => new digitalocean.DnsRecord('*', { domain: id, type: 'A', value: swarmMaster.ipv4Address, name: '*', }) ); const installAnsibleDepsCmd = new command.remote.Command( 'installAnsibleDepsCmd', { connection: { host: swarmMaster.ipv4Address, user: 'root', privateKey: privateKey, }, create: `apt-get update && apt-get install -y python3-pip python3-jsondiff`, } ); const deployDockerStackCmd = new command.local.Command( 'deployDockerStackCmd', { create: pulumi.interpolate`ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u root -i "${swarmMaster.ipv4Address}," --private-key ./private_key ansible/playbook.yml`, }, { dependsOn: [installAnsibleDepsCmd], } ); const restartCmd = new command.remote.Command( 'restartCmd', { connection: { host: swarmMaster.ipv4Address, user: 'root', privateKey: privateKey, }, create: `shutdown -r 0`, }, { dependsOn: [deployDockerStackCmd], } );