Skip to content

Commit

Permalink
Create infra and deployment commands
Browse files Browse the repository at this point in the history
  • Loading branch information
pziemkowski committed Sep 6, 2023
1 parent f169674 commit 1cee96a
Show file tree
Hide file tree
Showing 19 changed files with 143 additions and 32 deletions.
10 changes: 0 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(SELF_DIR)/Makefile.base.mk

bootstrap-infra:
pnpm nx run tools:bootstrap-infra
pnpm nx run --output-style=stream infra-shared:bootstrap

setup:
pnpm nx run-many --skip-nx-cache --target=setup --projects=core,backend,workers,webapp,e2e-tests
Expand All @@ -12,13 +9,6 @@ setup:
# Infrastructure deployment
#

deploy-env-infra:
pnpm nx run --output-style=stream infra-shared:deploy:global
pnpm nx run --output-style=stream infra-shared:deploy:main
pnpm nx run --output-style=stream infra-shared:deploy:db
pnpm nx run --output-style=stream infra-functions:deploy
pnpm nx run --output-style=stream infra-shared:deploy:ci
pnpm nx run --output-style=stream infra-shared:deploy:components

upload-version:
pnpm nx run --output-style=stream tools:upload-version migrations,api,workers,webapp
Expand Down
5 changes: 0 additions & 5 deletions Makefile.base.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ export HOST_UID
USER_SHELL=$(shell env | grep '^SHELL=' | cut -d '=' -f 2)



aws-login:
aws-vault login $(AWS_VAULT_PROFILE)


secrets-editor: SERVICE_NAME?=
secrets-editor:
pnpm nx run ssm-editor:compose-build-image
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@
"commands": ["nx cdk:deploy:api", "nx cdk:deploy:migrations"],
"parallel": false
}
},
"diff": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/backend",
"color": true,
"commands": ["nx diff:api", "nx diff:migrations"],
"parallel": false
}
}
},
"tags": ["service"]
Expand Down
1 change: 1 addition & 0 deletions packages/infra/infra-functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"build": "sls package",
"deploy": "sls deploy",
"diff": "echo 'no-diff-available'",
"remove": "sls remove"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/infra/infra-functions/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ provider:
runtime: nodejs16.x
versionFunctions: false
stage: "${env:ENV_STAGE}"
region: "${env:AWS_DEFAULT_REGION}"
region: "${env:AWS_REGION, env:AWS_DEFAULT_REGION}"
stackName: ${self:custom.conf.stackName}
iamRoleStatements: ${self:custom.conf.iam}
environment: ${self:custom.conf.environment}
Expand Down
18 changes: 18 additions & 0 deletions packages/internal/cli/src/commands/aws/deploy-app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Command } from '@oclif/core';

import { initConfig } from '../../config/init';
import { runCommand } from '../../lib/runCommand';

export default class DeployApp extends Command {
static description = 'Get currently selected ENV stage';

static examples = [`$ saas aws bootstrap`];

async run(): Promise<void> {
await initConfig(this, { requireAws: true });

await runCommand('pnpm', ['nx', 'run', 'backend:deploy']);
await runCommand('pnpm', ['nx', 'run', 'workers:deploy']);
await runCommand('pnpm', ['nx', 'run', 'webapp:deploy']);
}
}
2 changes: 1 addition & 1 deletion packages/internal/cli/src/commands/aws/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { initConfig } from '../../config/init';
import { runCommand } from '../../lib/runCommand';
import { assertAwsVaultInstalled } from '../../lib/awsVault';

export default class GetEnv extends Command {
export default class AwsLogin extends Command {
static description = 'Get currently selected ENV stage';

static examples = [`$ saas aws login`];
Expand Down
2 changes: 1 addition & 1 deletion packages/internal/cli/src/commands/backend/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { runCommand } from '../../lib/runCommand';
export default class BackendBuild extends Command {
static description = 'Starts all backend services';

static examples = [`$ saas backend up`];
static examples = [`$ <%= config.bin %> <%= command.id %>`];

async run(): Promise<void> {
const { envStage, version, awsRegion, awsAccountId } = await initConfig(
Expand Down
2 changes: 1 addition & 1 deletion packages/internal/cli/src/commands/backend/down.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { assertDockerIsRunning } from '../../lib/docker';
export default class BackendUp extends Command {
static description = 'Stops all backend services';

static examples = [`$ saas backend down`];
static examples = [`$ <%= config.bin %> <%= command.id %>`];

async run(): Promise<void> {
await initConfig(this, { requireLocalEnvStage: true });
Expand Down
9 changes: 3 additions & 6 deletions packages/internal/cli/src/commands/backend/remote-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import { initConfig } from '../../config/init';
import { runCommand } from '../../lib/runCommand';

export default class RemoteShell extends Command {
static description = 'Say hello world';
static description = 'Use aws execute-command to start a /bin/bash session inside a running backend task in ' +
'ECS cluster';

static examples = [
`<%= config.bin %> <%= command.id %>
hello world! (./src/commands/hello/world.ts)
`,
];
static examples = [`<%= config.bin %> <%= command.id %>`];

static flags = {};

Expand Down
33 changes: 33 additions & 0 deletions packages/internal/cli/src/commands/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Command, Flags } from '@oclif/core';

import { initConfig } from '../config/init';
import { runCommand } from '../lib/runCommand';

export default class Deploy extends Command {
static description = 'Starts both backend and frontend';

static examples = [`$ <%= config.bin %> <%= command.id %>`];

static flags = {
diff: Flags.boolean({
default: false,
description:
'Perform a dry run and list all changes that would be applied in AWS account',
required: false,
}),
};

async run(): Promise<void> {
const { flags } = await this.parse(Deploy);
await initConfig(this, { requireAws: true });

const verb = flags.diff ? 'diff' : 'deploy';
await runCommand('pnpm', [
'nx',
'run-many',
'--output-style=stream',
`--target=${verb}`,
'--projects=backend,workers,webapp',
]);
}
}
22 changes: 22 additions & 0 deletions packages/internal/cli/src/commands/infra/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Command } from '@oclif/core';

import { initConfig } from '../../config/init';
import { runCommand } from '../../lib/runCommand';

export default class InfraBootstrap extends Command {
static description =
'Bootstrap infrastructure in AWS account by creating resources necessary to start working with SaaS ' +
'Boilerplate';

static examples = [`<%= config.bin %> <%= command.id %>`];

async run(): Promise<void> {
await initConfig(this, {
requireAws: true,
validateEnvStageVariables: false,
});

await runCommand('pnpm', ['nx', 'run', 'tools:bootstrap-infra']);
await runCommand('pnpm', ['nx', 'run', 'infra-shared:bootstrap']);
}
}
33 changes: 33 additions & 0 deletions packages/internal/cli/src/commands/infra/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Command, Flags } from '@oclif/core';

import { initConfig } from '../../config/init';
import { runCommand } from '../../lib/runCommand';

export default class InfraDeploy extends Command {
static description =
'Deploy infrastructure of a currently selected environment stage to AWS account';

static examples = [`$ <%= config.bin %> <%= command.id %>`];

static flags = {
diff: Flags.boolean({
default: false,
description:
'Perform a dry run and list all changes that would be applied',
required: false,
}),
};

async run(): Promise<void> {
const { flags } = await this.parse(InfraDeploy);
await initConfig(this, { requireAws: true });

const verb = flags.diff ? 'diff' : 'deploy';
await runCommand('pnpm', ['nx', 'run', `infra-shared:${verb}:global`]);
await runCommand('pnpm', ['nx', 'run', `infra-shared:${verb}:main`]);
await runCommand('pnpm', ['nx', 'run', `infra-shared:${verb}:db`]);
await runCommand('pnpm', ['nx', 'run', `infra-functions:${verb}`]);
await runCommand('pnpm', ['nx', 'run', `infra-shared:${verb}:ci`]);
await runCommand('pnpm', ['nx', 'run', `infra-shared:${verb}:components`]);
}
}
2 changes: 1 addition & 1 deletion packages/internal/cli/src/commands/webapp/up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { runCommand } from '../../lib/runCommand';
export default class WebappUp extends Command {
static description = 'Starts frontend service';

static examples = [`$ saas webapp up`];
static examples = [`$ <%= config.bin %> <%= command.id %>`];

async run(): Promise<void> {
await initConfig(this, { requireLocalEnvStage: true });
Expand Down
3 changes: 2 additions & 1 deletion packages/internal/cli/src/config/aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ async function loadStageEnv(
Object.keys(parsed).length
} environmental variables from SSM Parameter Store using chamber.\n`
);

// @ts-ignore
dotenv.populate(process.env, parsed);
dotenv.populate(process.env, parsed, { override: true });

if (shouldValidate) {
await validateStageEnv();
Expand Down
4 changes: 2 additions & 2 deletions packages/internal/cli/src/config/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { resolve } from 'path';

import { ENV_STAGE_LOCAL, loadDotenv, loadVersionEnv } from './env';
import { initAWS } from './aws';
import { getEnvStage } from './storage';
import { loadEnvStage } from './storage';

const exec = promisify(childProcess.exec);

Expand All @@ -34,7 +34,7 @@ export const initConfig = async (
const rootPath = await getRootPath();
await loadDotenv({ rootPath });
const version = await loadVersionEnv();
const envStage = await getEnvStage();
const envStage = await loadEnvStage();
const projectName = process.env.PROJECT_NAME;

if (!projectName) {
Expand Down
6 changes: 4 additions & 2 deletions packages/internal/cli/src/config/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ export const getConfigStorage = async () => {
return storage;
};

export const getEnvStage = async (): Promise<string> => {
export const loadEnvStage = async (): Promise<string> => {
const storage = await getConfigStorage();
return (await storage.getItem(getEnvStageKey())) ?? ENV_STAGE_LOCAL;
const value = (await storage.getItem(getEnvStageKey())) ?? ENV_STAGE_LOCAL;
process.env.ENV_STAGE = value;
return value;
};

export const setEnvStage = async (value: string) => {
Expand Down
9 changes: 9 additions & 0 deletions packages/webapp/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@
],
"parallel": false
}
},
"diff": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/webapp",
"color": true,
"commands": ["pnpm run cdk diff *WebAppStack"],
"parallel": false
}
}
},
"tags": []
Expand Down
3 changes: 2 additions & 1 deletion packages/workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"stop-task-scheduling-executions": "/bin/bash ./scripts/stop-task-scheduling-executions.sh",
"lint:js": "eslint .",
"sls": "sls",
"serverless": "serverless"
"serverless": "serverless",
"diff": "echo 'no-diff-available'"
},
"author": "",
"license": "ISC",
Expand Down

0 comments on commit 1cee96a

Please sign in to comment.