bromanko / capemay

1 stars 0 forks source link

Create and Deploy Tenant apps #2

Open bromanko opened 1 year ago

bromanko commented 1 year ago

I'll make a command that will be executed via a forthcoming task runner. The command needs to be idempotent. It's similar to the deploy-admin-server.sh script used to deploy the admin app; difference being the deployed image will be prebuilt and configured as part of the task-runner configuration.

I'll name the command DeployConsumerServer since that's what I've called the consumer-facing server. I chose this over DeployTenant since I anticipate tenants may have multiple components which will be deployed separately.

App naming

Fly.io apps need a unique name. I'll use the tenant fqdn as the name.

Pseudo code

if appExists $app then
  log "app exists. do nothing"
else
    log "Creating app $app..."
    createApp $app
end if

if volumeExists $app then
    log "Volume exists. Skipping creation."
else
    log "Creating volume..."
    createVolume $app
end if

if machineExists $app then
    log "Machine exists. Updating..."
    updateMachine ${app} ${volume_name}
else
    log "Creating machine..."
    create ${app} ${volume_name}
end if
bromanko commented 1 year ago

Let's sort out the queries first.

Checking if things exist

I can write a single Graphql query to check if the app, volume, and machine are all setup.

query($appName: String!) {
  app(name: $appName) {
    appUrl,
    createdAt,
    deployed,
    hostname,
    id,
    name,
    organization { id, name }
    regions { name, code  },
    status,
    machines {
      nodes {
        name
        id
        ips {
          nodes {
            id
            ip
            kind
            family
          }
        }
      }
    },
    volumes {
      nodes {
        id
        name
        sizeGb
        state
        status
        usedBytes
      }
    }
  }
}
bromanko commented 1 year ago

Keeping in mind "functional core, imperative shell" I'll use the single query as the source of truth for further logic. Create a data structure that represents the corresponding mutations to make, then aggregate the results in a response data structure.

Pseudo code


let mkMutations qry =
  let mutations = []
  match qry.app with 
  | None -> mutations ++ [mkApp; mkVolume; mkMachine]
  | Some { app.volumes.Length <= 0 } -> mutations ++ [mkVolume]
  | Some { app.machines.Length <= 0 } -> mutations ++ [mkMachine]
  mutations

let client = mkClient "token"
client.GetApp "app-name"
|> mkMutations
|> execMutations
|> updateDb

For the mkMachine call, this should update the deployment to the latest version if the machine exists.

Mutations

Db Schema

At this point I don't have a use for storing information about the deployment. I'm not going to.

bromanko commented 1 year ago

Turns out I can't use the Graphql api to create the machine deployment. This must be done with the REST api:

An unexpected error occurred. The launchMachine endpoint has reached its EOL. Please visit https://fly.io/docs/reference/machines/ for more information on how to leverage our new Machines API!

I'll make a REST API client for these two calls.

bromanko commented 1 year ago

I need to pass the deployment configuration to machines. I think I'd prefer this to be stored as a json file for ease of use.