avicenna/infrastructure/single-docker-server/index.ts

242 lines
5.7 KiB
TypeScript

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;
const env = pulumi.getStack();
if (!fs.existsSync(`./.local/${env}`)) {
fs.mkdirSync(`./.local/${env}`);
}
privateKey.apply((privKey) =>
fs.writeFileSync(`./.local/${env}/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 doToken = config.getSecret('doToken');
if (doToken) {
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 ./.local/${env}/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],
}
);