adhoc-deploy 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 20.18.0
package/Dockerfile ADDED
@@ -0,0 +1,18 @@
1
+ FROM node:20.18.0
2
+
3
+ WORKDIR /usr/src/app
4
+
5
+ COPY package.json /usr/src/app/
6
+
7
+ RUN npm install
8
+
9
+ RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
10
+ unzip awscliv2.zip && \
11
+ ./aws/install
12
+
13
+ RUN apt-get update && \
14
+ apt-get -y install zip
15
+
16
+ COPY . /usr/src/app/
17
+
18
+ CMD [ "node", "index.mjs" ]
package/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # adhoc-deploy
2
+
3
+ AWS Batch job container for deploying QA/Demo environments.
4
+
5
+ ## Deploy
6
+
7
+ You must be logged in using the wp-role profile and have Docker running.
8
+
9
+ 1. `npm run deploy`
10
+ 2. `npm run deploy:verify`
11
+
12
+ ## Bootstrap
13
+
14
+ Run `npm run bootstrap` after modifying job definitions in `aws-config/` to register updated definitions with AWS Batch.
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ # Register updated Batch job definitions with disable_discord_notifications parameter
4
+
5
+ aws batch register-job-definition --profile wp-role --cli-input-json file://qa-api-deploy.json
6
+ aws batch register-job-definition --profile wp-role --cli-input-json file://qa-webapp-deploy.json
7
+ aws batch register-job-definition --profile wp-role --cli-input-json file://demo-api-deploy.json
8
+ aws batch register-job-definition --profile wp-role --cli-input-json file://demo-webapp-deploy.json
9
+
10
+ echo "✅ All job definitions updated"
@@ -0,0 +1,88 @@
1
+ {
2
+ "jobDefinitionName": "demo-api-deploy",
3
+ "type": "container",
4
+ "parameters": {
5
+ "branch": "master"
6
+ },
7
+ "retryStrategy": {
8
+ "attempts": 1,
9
+ "evaluateOnExit": []
10
+ },
11
+ "containerProperties": {
12
+ "image": "147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments",
13
+ "command": [
14
+ "node",
15
+ "index.mjs",
16
+ "--branch",
17
+ "Ref::branch",
18
+ "--disable_discord_notifications",
19
+ "Ref::disable_discord_notifications"
20
+ ],
21
+ "jobRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
22
+ "executionRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
23
+ "volumes": [],
24
+ "environment": [
25
+ {
26
+ "name": "AWS_REGION",
27
+ "value": "us-east-1"
28
+ },
29
+ {
30
+ "name": "REPO_KEY_URL",
31
+ "value": "s3://wholesalepayroll-com-batch-deployments/configuration/wp-code-deploy-api"
32
+ },
33
+ {
34
+ "name": "ARTIFACT_URL",
35
+ "value": "s3://wholesalepayroll-com-batch-deployments/builds/demo/api/source.zip"
36
+ },
37
+ {
38
+ "name": "REPO_URL",
39
+ "value": "git@github.com:WholesalePayroll/service-layer.git"
40
+ },
41
+ {
42
+ "name": "VPC_ID",
43
+ "value": "vpc-097160e523f14ec6f"
44
+ },
45
+ {
46
+ "name": "LAUNCH_TEMPLATE",
47
+ "value": "lt-0f04c819ccc51da3d,lt-0e546a64ec43647b6"
48
+ },
49
+ {
50
+ "name": "SOURCE_PACKAGE",
51
+ "value": "api.zip"
52
+ },
53
+ {
54
+ "name": "GIT_SSH_COMMAND",
55
+ "value": "ssh -i ~/.ssh/wp-code-deploy -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
56
+ }
57
+ ],
58
+ "mountPoints": [],
59
+ "ulimits": [],
60
+ "resourceRequirements": [
61
+ {
62
+ "value": "1",
63
+ "type": "VCPU"
64
+ },
65
+ {
66
+ "value": "1024",
67
+ "type": "MEMORY"
68
+ }
69
+ ],
70
+ "logConfiguration": {
71
+ "logDriver": "awslogs",
72
+ "options": {},
73
+ "secretOptions": []
74
+ },
75
+ "secrets": []
76
+ },
77
+ "timeout": {
78
+ "attemptDurationSeconds": 600
79
+ },
80
+ "tags": {
81
+ "Role": "api",
82
+ "Environment": "demo"
83
+ },
84
+ "propagateTags": false,
85
+ "platformCapabilities": [
86
+ "EC2"
87
+ ]
88
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "jobDefinitionName": "demo-webapp-deploy",
3
+ "type": "container",
4
+ "parameters": {
5
+ "branch": "master"
6
+ },
7
+ "retryStrategy": {
8
+ "attempts": 1,
9
+ "evaluateOnExit": []
10
+ },
11
+ "containerProperties": {
12
+ "image": "147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments",
13
+ "command": [
14
+ "node",
15
+ "index.mjs",
16
+ "--branch",
17
+ "Ref::branch",
18
+ "--disable_discord_notifications",
19
+ "Ref::disable_discord_notifications"
20
+ ],
21
+ "jobRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
22
+ "executionRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
23
+ "volumes": [],
24
+ "environment": [
25
+ {
26
+ "name": "AWS_REGION",
27
+ "value": "us-east-1"
28
+ },
29
+ {
30
+ "name": "REPO_KEY_URL",
31
+ "value": "s3://wholesalepayroll-com-batch-deployments/configuration/wp-code-deploy"
32
+ },
33
+ {
34
+ "name": "ARTIFACT_URL",
35
+ "value": "s3://wholesalepayroll-com-batch-deployments/builds/demo/web/source.zip"
36
+ },
37
+ {
38
+ "name": "REPO_URL",
39
+ "value": "git@github.com:WholesalePayroll/web-application.git"
40
+ },
41
+ {
42
+ "name": "VPC_ID",
43
+ "value": "vpc-097160e523f14ec6f"
44
+ },
45
+ {
46
+ "name": "LAUNCH_TEMPLATE",
47
+ "value": "lt-05f023dfa7b4e668e"
48
+ },
49
+ {
50
+ "name": "SOURCE_PACKAGE",
51
+ "value": "webapp.zip"
52
+ },
53
+ {
54
+ "name": "GIT_SSH_COMMAND",
55
+ "value": "ssh -i ~/.ssh/wp-code-deploy -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
56
+ }
57
+ ],
58
+ "mountPoints": [],
59
+ "ulimits": [],
60
+ "resourceRequirements": [
61
+ {
62
+ "value": "1",
63
+ "type": "VCPU"
64
+ },
65
+ {
66
+ "value": "1024",
67
+ "type": "MEMORY"
68
+ }
69
+ ],
70
+ "logConfiguration": {
71
+ "logDriver": "awslogs",
72
+ "options": {},
73
+ "secretOptions": []
74
+ },
75
+ "secrets": []
76
+ },
77
+ "timeout": {
78
+ "attemptDurationSeconds": 600
79
+ },
80
+ "tags": {
81
+ "Role": "webapp",
82
+ "Environment": "demo"
83
+ },
84
+ "propagateTags": false,
85
+ "platformCapabilities": [
86
+ "EC2"
87
+ ]
88
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "jobDefinitionName": "qa-api-deploy",
3
+ "type": "container",
4
+ "parameters": {
5
+ "branch": "master"
6
+ },
7
+ "retryStrategy": {
8
+ "attempts": 1,
9
+ "evaluateOnExit": []
10
+ },
11
+ "containerProperties": {
12
+ "image": "147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments",
13
+ "command": [
14
+ "node",
15
+ "index.mjs",
16
+ "--branch",
17
+ "Ref::branch",
18
+ "--disable_discord_notifications",
19
+ "Ref::disable_discord_notifications"
20
+ ],
21
+ "jobRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
22
+ "executionRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
23
+ "volumes": [],
24
+ "environment": [
25
+ {
26
+ "name": "AWS_REGION",
27
+ "value": "us-east-1"
28
+ },
29
+ {
30
+ "name": "REPO_KEY_URL",
31
+ "value": "s3://wholesalepayroll-com-batch-deployments/configuration/wp-code-deploy-api"
32
+ },
33
+ {
34
+ "name": "ARTIFACT_URL",
35
+ "value": "s3://wholesalepayroll-com-batch-deployments/builds/qa/api/source.zip"
36
+ },
37
+ {
38
+ "name": "REPO_URL",
39
+ "value": "git@github.com:WholesalePayroll/service-layer.git"
40
+ },
41
+ {
42
+ "name": "VPC_ID",
43
+ "value": "vpc-097160e523f14ec6f"
44
+ },
45
+ {
46
+ "name": "LAUNCH_TEMPLATE",
47
+ "value": "lt-0d81fd1772f186129,lt-02cd3cda3bdad1e9f"
48
+ },
49
+ {
50
+ "name": "SOURCE_PACKAGE",
51
+ "value": "api.zip"
52
+ },
53
+ {
54
+ "name": "GIT_SSH_COMMAND",
55
+ "value": "ssh -i ~/.ssh/wp-code-deploy -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
56
+ }
57
+ ],
58
+ "mountPoints": [],
59
+ "ulimits": [],
60
+ "resourceRequirements": [
61
+ {
62
+ "value": "1",
63
+ "type": "VCPU"
64
+ },
65
+ {
66
+ "value": "1024",
67
+ "type": "MEMORY"
68
+ }
69
+ ],
70
+ "logConfiguration": {
71
+ "logDriver": "awslogs",
72
+ "options": {},
73
+ "secretOptions": []
74
+ },
75
+ "secrets": []
76
+ },
77
+ "timeout": {
78
+ "attemptDurationSeconds": 600
79
+ },
80
+ "tags": {
81
+ "Role": "api",
82
+ "Environment": "qa"
83
+ },
84
+ "propagateTags": false,
85
+ "platformCapabilities": [
86
+ "EC2"
87
+ ]
88
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "jobDefinitionName": "qa-webapp-deploy",
3
+ "type": "container",
4
+ "parameters": {
5
+ "branch": "master"
6
+ },
7
+ "retryStrategy": {
8
+ "attempts": 1,
9
+ "evaluateOnExit": []
10
+ },
11
+ "containerProperties": {
12
+ "image": "147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments",
13
+ "command": [
14
+ "node",
15
+ "index.mjs",
16
+ "--branch",
17
+ "Ref::branch",
18
+ "--disable_discord_notifications",
19
+ "Ref::disable_discord_notifications"
20
+ ],
21
+ "jobRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
22
+ "executionRoleArn": "arn:aws:iam::147724020626:role/any-deployer-batch-task",
23
+ "volumes": [],
24
+ "environment": [
25
+ {
26
+ "name": "AWS_REGION",
27
+ "value": "us-east-1"
28
+ },
29
+ {
30
+ "name": "REPO_KEY_URL",
31
+ "value": "s3://wholesalepayroll-com-batch-deployments/configuration/wp-code-deploy"
32
+ },
33
+ {
34
+ "name": "ARTIFACT_URL",
35
+ "value": "s3://wholesalepayroll-com-batch-deployments/builds/qa/web/source.zip"
36
+ },
37
+ {
38
+ "name": "REPO_URL",
39
+ "value": "git@github.com:WholesalePayroll/web-application.git"
40
+ },
41
+ {
42
+ "name": "VPC_ID",
43
+ "value": "vpc-097160e523f14ec6f"
44
+ },
45
+ {
46
+ "name": "LAUNCH_TEMPLATE",
47
+ "value": "lt-03169692c25c944ba"
48
+ },
49
+ {
50
+ "name": "SOURCE_PACKAGE",
51
+ "value": "webapp.zip"
52
+ },
53
+ {
54
+ "name": "GIT_SSH_COMMAND",
55
+ "value": "ssh -i ~/.ssh/wp-code-deploy -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
56
+ }
57
+ ],
58
+ "mountPoints": [],
59
+ "ulimits": [],
60
+ "resourceRequirements": [
61
+ {
62
+ "value": "1",
63
+ "type": "VCPU"
64
+ },
65
+ {
66
+ "value": "1024",
67
+ "type": "MEMORY"
68
+ }
69
+ ],
70
+ "logConfiguration": {
71
+ "logDriver": "awslogs",
72
+ "options": {},
73
+ "secretOptions": []
74
+ },
75
+ "secrets": []
76
+ },
77
+ "timeout": {
78
+ "attemptDurationSeconds": 600
79
+ },
80
+ "tags": {
81
+ "Role": "webapp",
82
+ "Environment": "qa"
83
+ },
84
+ "propagateTags": false,
85
+ "platformCapabilities": [
86
+ "EC2"
87
+ ]
88
+ }
package/config.mjs ADDED
@@ -0,0 +1,41 @@
1
+ class Config {
2
+ constructor(args) {
3
+ this._artifactUrl = process.env.ARTIFACT_URL;
4
+ this._branch = args.branch;
5
+ this._disableDiscordNotifications = args.disable_discord_notifications;
6
+ this._launchTemplateId = process.env.LAUNCH_TEMPLATE.split(",");
7
+ this._repoSshKey = process.env.REPO_KEY_URL;
8
+ this._repoUrl = process.env.REPO_URL;
9
+ this._vpcId = process.env.VPC_ID;
10
+ }
11
+
12
+ get artifactUrl() {
13
+ return this._artifactUrl;
14
+ }
15
+
16
+ get branch() {
17
+ return this._branch;
18
+ }
19
+
20
+ get disableDiscordNotifications() {
21
+ return this._disableDiscordNotifications;
22
+ }
23
+
24
+ get launchTemplateIds() {
25
+ return this._launchTemplateId;
26
+ }
27
+
28
+ get repoSshKey() {
29
+ return this._repoSshKey;
30
+ }
31
+
32
+ get repoUrl() {
33
+ return this._repoUrl;
34
+ }
35
+
36
+ get vpcId() {
37
+ return this._vpcId;
38
+ }
39
+ }
40
+
41
+ export default Config;
package/index.mjs ADDED
@@ -0,0 +1,271 @@
1
+ import {
2
+ EC2Client,
3
+ DescribeInstancesCommand,
4
+ DescribeSubnetsCommand,
5
+ RunInstancesCommand
6
+ } from "@aws-sdk/client-ec2";
7
+
8
+ import {
9
+ ExecuteStatementCommand,
10
+ RDSDataClient
11
+ } from "@aws-sdk/client-rds-data";
12
+
13
+ import {
14
+ SNSClient,
15
+ PublishCommand
16
+ } from "@aws-sdk/client-sns";
17
+
18
+ const argDefinition = [
19
+ { name: "branch", alias: "b", type: String },
20
+ { name: "disable_discord_notifications", type: String }
21
+ ];
22
+
23
+ import commandLineArgs from "command-line-args";
24
+ const commandOptions = commandLineArgs(argDefinition);
25
+
26
+ console.dir(commandOptions);
27
+
28
+ import Config from "./config.mjs";
29
+ const config = new Config(commandOptions);
30
+
31
+ import os from "os";
32
+ import path from "path";
33
+ import fs from "fs";
34
+ import child_process from "child_process";
35
+
36
+ const ec2Client = new EC2Client();
37
+ const rdsClient = new RDSDataClient();
38
+ const snsClient = new SNSClient();
39
+
40
+ async function checkExistingInstance() {
41
+ // Fortunately AWS tags instances created from a launch template.
42
+ // So we just need to see if an existing instance can be found
43
+ for (const launchTemplateId of config.launchTemplateIds) {
44
+ const describeInstancesCommand = new DescribeInstancesCommand({
45
+ Filters: [
46
+ { Name: "tag:aws:ec2launchtemplate:id", Values: [launchTemplateId] },
47
+ { Name: "instance-state-name", Values: ["running"]}
48
+ ]
49
+ });
50
+
51
+ const response = await ec2Client.send(describeInstancesCommand);
52
+ console.log(JSON.stringify(response));
53
+
54
+ const reservation = (response.Reservations && response.Reservations[0]);
55
+ if (reservation && reservation.Instances && reservation.Instances.length > 0) {
56
+ return true;
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+
62
+ async function createDeploymentArtifact() {
63
+ const sshPath = path.join(os.homedir(),".ssh");
64
+ const keyPath = path.format({
65
+ dir: sshPath,
66
+ name: "wp-code-deploy"
67
+ });
68
+ console.log(`Writing private deployment key to ${keyPath}`);
69
+ fs.mkdirSync(sshPath);
70
+
71
+ downloadFileFromS3(config.repoSshKey, keyPath);
72
+ fs.chmodSync(keyPath, fs.constants.S_IRUSR | fs.constants.S_IWUSR);
73
+
74
+ console.log(`Fetching git repo ${config.repoUrl}...`);
75
+ const cloneArgs = ["clone", config.repoUrl, "code-staging"];
76
+ const gitResult = child_process.spawnSync(
77
+ "git",
78
+ cloneArgs,
79
+ { cwd: os.tmpdir() }
80
+ );
81
+ reportSpawnError(gitResult);
82
+
83
+ const codeWorkingDir = path.join(os.tmpdir(), "code-staging");
84
+
85
+ // now switch to the desired branch
86
+ console.log("changing branches...");
87
+ const gitBranchResult = child_process.spawnSync(
88
+ "git",
89
+ ["checkout", config.branch],
90
+ { cwd: codeWorkingDir }
91
+ );
92
+ reportSpawnError(gitBranchResult);
93
+
94
+ // Now run the zip builder
95
+ console.log("building zip....");
96
+ const zipBuildResult = child_process.spawnSync(
97
+ "npm",
98
+ ["run", "deploy-aws"],
99
+ { cwd: codeWorkingDir }
100
+ );
101
+ reportSpawnError(zipBuildResult);
102
+
103
+ // And finally upload the results to s3
104
+ const uploadResult = child_process.spawnSync(
105
+ "aws",
106
+ ["s3","cp", process.env.SOURCE_PACKAGE, config.artifactUrl],
107
+ { cwd: codeWorkingDir }
108
+ );
109
+ reportSpawnError(uploadResult);
110
+
111
+ // Publish to topic
112
+ const unused1 = await publishProgress({
113
+ type: "batch:job",
114
+ step: "source:build",
115
+ status: "success"
116
+ });
117
+ return true;
118
+ }
119
+
120
+ async function createInstance() {
121
+ const instancePromises = [];
122
+
123
+ for (const launchTemplateId of config.launchTemplateIds) {
124
+ // create the instance using the launch template specified
125
+ const commandInput = {};
126
+ commandInput.LaunchTemplate = {
127
+ LaunchTemplateId: launchTemplateId,
128
+ Version: "$Default"
129
+ };
130
+ commandInput.MaxCount = 1;
131
+ commandInput.MinCount = 1;
132
+
133
+ const subnet = await getRandomSubnetForVPC();
134
+ commandInput.SubnetId = subnet.SubnetId;
135
+
136
+ console.dir(`CommandInput => ${commandInput}`);
137
+ const runCommand = new RunInstancesCommand(commandInput);
138
+ const response = await ec2Client.send(runCommand);
139
+ const instance = response && response.Instances && response.Instances[0];
140
+ if (!instance) {
141
+ throw new Error("Unable to create new instance");
142
+ }
143
+ console.log(`instance started => ${instance.InstanceId}`);
144
+
145
+ const describeCommand = new DescribeInstancesCommand({
146
+ InstanceIds: [instance.InstanceId]
147
+ });
148
+ instancePromises.push(
149
+ new Promise((resolve, reject) => {
150
+ const interval = setInterval(
151
+ async () => {
152
+ console.log("polling for state....")
153
+ const describeResponse = await ec2Client.send(describeCommand);
154
+ const reservation = describeResponse.Reservations && describeResponse.Reservations[0];
155
+ const foundInstance = reservation.Instances && reservation.Instances[0];
156
+ console.log(`received ${foundInstance}`);
157
+ if (foundInstance && foundInstance.State.Name == "running") {
158
+ const unused2 = await publishProgress({
159
+ type: "batch:job",
160
+ step: "instance:create",
161
+ status: "success"
162
+ });
163
+ resolve(foundInstance);
164
+ }
165
+ },
166
+ 30000
167
+ );
168
+ })
169
+ );
170
+ }
171
+ return Promise.all(instancePromises);
172
+ }
173
+
174
+ function downloadFileFromS3(s3Uri, outputPath) {
175
+ const downloadResult = child_process.spawnSync(
176
+ "aws",
177
+ ["s3","cp", s3Uri, outputPath]
178
+ );
179
+ reportSpawnError(downloadResult);
180
+ }
181
+
182
+ async function getRandomSubnetForVPC() {
183
+ console.log(`Fetching subnets for => ${config.vpcId}`);
184
+
185
+ const command = new DescribeSubnetsCommand({
186
+ Filters: [
187
+ { Name: "vpc-id", Values: [config.vpcId] },
188
+ { Name: "tag-key", Values: ["IncludeDeployments"] }
189
+ ]
190
+ });
191
+ const response = await ec2Client.send(command);
192
+ const subnets = response.Subnets;
193
+ subnets.forEach((subnet) => { console.log(subnet.SubnetId); });
194
+ const subnetIndex = Math.floor(Math.random() * subnets.length)
195
+ console.log(`Found subnet => ${subnets[subnetIndex].SubnetId}`);
196
+ return subnets[subnetIndex];
197
+ }
198
+
199
+ async function main() {
200
+ console.log("Checking for existing instance...");
201
+ const instanceCheck = await checkExistingInstance();
202
+ if (instanceCheck) {
203
+ const unused = await publishProgress({
204
+ type: "batch:job",
205
+ step: "instance:check",
206
+ status: "failed"
207
+ });
208
+ process.exit(-1);
209
+ }
210
+
211
+ await wakeupDatabaseCluster();
212
+ await createInstance();
213
+ await createDeploymentArtifact();
214
+ }
215
+
216
+ async function publishProgress(message) {
217
+ // Skip Discord notifications if disabled (GitHub Actions deployments)
218
+ // Parameter is optional - Discord Lambda doesn't pass it, only GitHub Actions does
219
+ if (config.disableDiscordNotifications === "true") {
220
+ console.log("Discord notifications disabled, skipping SNS publish:", message);
221
+ return;
222
+ }
223
+
224
+ const publishCommand = new PublishCommand({
225
+ Message: JSON.stringify(message),
226
+ TopicArn: "arn:aws:sns:us-east-1:147724020626:deployment-progress"
227
+ });
228
+ return snsClient.send(publishCommand);
229
+ }
230
+
231
+ function reportSpawnError(spawnResult) {
232
+ console.log(`spawn output: ${spawnResult.stdout.toString()}`);
233
+ console.log(`spawn error: ${spawnResult.stderr.toString()}`);
234
+ if (spawnResult.error) {
235
+ throw new Error(zipBuildResult.error)
236
+ }
237
+ if (spawnResult.status) {
238
+ throw new Error(zipBuildResult.status)
239
+ }
240
+ }
241
+
242
+ async function wakeupDatabaseCluster() {
243
+ // RJTODO: move some of these strings out of code
244
+ const command = new ExecuteStatementCommand({
245
+ continueAfterTimeout: false,
246
+ database: "payroll",
247
+ includeResultMetadata: true,
248
+ resourceArn: "arn:aws:rds:us-east-1:147724020626:cluster:staging-2022-02-12",
249
+ secretArn: "arn:aws:secretsmanager:us-east-1:147724020626:secret:staging/rds/connection-RuggqK",
250
+ sql: "select count(id) from default_config"
251
+ });
252
+ try {
253
+ const response = await rdsClient.send(command);
254
+ } catch (error) {
255
+ console.log("error while booting rds");
256
+ console.log(error);
257
+ }
258
+ }
259
+
260
+ try {
261
+ await main();
262
+ process.exit(0);
263
+ } catch (err) {
264
+ const unused = await publishProgress({
265
+ type: "batch:job",
266
+ step: "unknown",
267
+ status: "failed"
268
+ });
269
+ console.error(err);
270
+ process.exit(1);
271
+ }
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "adhoc-deploy",
3
+ "version": "1.1.0",
4
+ "scripts": {
5
+ "bootstrap": "cd aws-config && ./bootstrap.sh",
6
+ "build": "npm run clean && npx tsc",
7
+ "clean": "rimraf dist",
8
+ "ecr:build": "docker build --platform linux/amd64 -t deployments .",
9
+ "ecr:login": "aws ecr get-login-password --region us-east-1 --profile wp-role | docker login --username AWS --password-stdin 147724020626.dkr.ecr.us-east-1.amazonaws.com",
10
+ "ecr:publish": "docker tag deployments:latest 147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments:latest && docker push 147724020626.dkr.ecr.us-east-1.amazonaws.com/deployments:latest",
11
+ "deploy": "npm run ecr:build && npm run ecr:login && npm run ecr:publish",
12
+ "deploy:verify": "aws ecr describe-images --repository-name deployments --image-ids imageTag=latest --profile wp-role",
13
+ "test": "echo \"Error: no test specified\" && exit 1"
14
+ },
15
+ "dependencies": {
16
+ "@aws-sdk/client-ec2": "^3.49.0",
17
+ "@aws-sdk/client-rds-data": "^3.72.0",
18
+ "@aws-sdk/client-s3": "^3.50.0",
19
+ "@aws-sdk/client-sns": "^3.51.0",
20
+ "@aws-sdk/client-ssm": "^3.50.0",
21
+ "command-line-args": "^5.2.1",
22
+ "dotenv": "^16.0.0"
23
+ }
24
+ }