@studion/infra-code-blocks 0.0.9 → 0.0.11
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/README.md +37 -4
- package/dist/components/database.d.ts +6 -4
- package/dist/components/database.js +14 -1
- package/dist/components/project.d.ts +2 -1
- package/dist/components/project.js +3 -2
- package/dist/components/redis.d.ts +3 -0
- package/dist/components/redis.js +11 -0
- package/dist/components/static-site.js +0 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ type DatabaseService = {
|
|
|
92
92
|
serviceName: string;
|
|
93
93
|
dbName: pulumi.Input<string>;
|
|
94
94
|
username: pulumi.Input<string>;
|
|
95
|
-
password
|
|
95
|
+
password?: pulumi.Input<string>;
|
|
96
96
|
applyImmediately?: pulumi.Input<boolean>;
|
|
97
97
|
skipFinalSnapshot?: pulumi.Input<boolean>;
|
|
98
98
|
allocatedStorage?: pulumi.Input<number>;
|
|
@@ -131,7 +131,7 @@ export type WebServerService = {
|
|
|
131
131
|
environment?:
|
|
132
132
|
| aws.ecs.KeyValuePair[]
|
|
133
133
|
| ((services: Services) => aws.ecs.KeyValuePair[]);
|
|
134
|
-
secrets?: aws.ecs.Secret[];
|
|
134
|
+
secrets?: aws.ecs.Secret[] | ((services: Services) => aws.ecs.Secret[]);
|
|
135
135
|
image: pulumi.Input<string>;
|
|
136
136
|
port: pulumi.Input<number>;
|
|
137
137
|
domain: pulumi.Input<string>;
|
|
@@ -203,6 +203,33 @@ const project = new studion.Project('demo-project', {
|
|
|
203
203
|
});
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
+
```ts
|
|
207
|
+
const project = new studion.Project('demo-project', {
|
|
208
|
+
environment: 'DEVELOPMENT',
|
|
209
|
+
services: [
|
|
210
|
+
{
|
|
211
|
+
type: 'REDIS',
|
|
212
|
+
serviceName: 'redis',
|
|
213
|
+
dbName: 'test-db',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
type: 'WEB_SERVER',
|
|
217
|
+
serviceName: 'api',
|
|
218
|
+
image: imageUri,
|
|
219
|
+
port: 3000,
|
|
220
|
+
domain: 'api.my-domain.com',
|
|
221
|
+
secrets: (services: Services) => {
|
|
222
|
+
const redisServiceName = 'redis';
|
|
223
|
+
const redis = services[redisServiceName];
|
|
224
|
+
return [
|
|
225
|
+
{ name: 'REDIS_PASSWORD', valueFrom: redis.passwordSecret.arn },
|
|
226
|
+
];
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
206
233
|
### Database
|
|
207
234
|
|
|
208
235
|
AWS RDS Postgres instance.
|
|
@@ -229,8 +256,8 @@ new Database(name: string, args: DatabaseArgs, opts?: pulumi.CustomResourceOptio
|
|
|
229
256
|
type DatabaseArgs = {
|
|
230
257
|
dbName: pulumi.Input<string>;
|
|
231
258
|
username: pulumi.Input<string>;
|
|
232
|
-
password: pulumi.Input<string>;
|
|
233
259
|
vpc: awsx.ec2.Vpc;
|
|
260
|
+
password?: pulumi.Input<string>;
|
|
234
261
|
applyImmediately?: pulumi.Input<boolean>;
|
|
235
262
|
skipFinalSnapshot?: pulumi.Input<boolean>;
|
|
236
263
|
allocatedStorage?: pulumi.Input<number>;
|
|
@@ -242,6 +269,10 @@ type DatabaseArgs = {
|
|
|
242
269
|
};
|
|
243
270
|
```
|
|
244
271
|
|
|
272
|
+
If a password is not specified, it will be autogenerated and stored as a secret
|
|
273
|
+
inside AWS Secret Manager. The secret will be available on the `Database` resource
|
|
274
|
+
as `passwordSecret`.
|
|
275
|
+
|
|
245
276
|
### Redis
|
|
246
277
|
|
|
247
278
|
[Upstash](https://upstash.com) Redis instance.
|
|
@@ -283,6 +314,9 @@ interface RedisOptions extends pulumi.ComponentResourceOptions {
|
|
|
283
314
|
}
|
|
284
315
|
```
|
|
285
316
|
|
|
317
|
+
After creating the Redis resource, the `passwordSecret` AWS Secret Manager Secret
|
|
318
|
+
will exist on the resource.
|
|
319
|
+
|
|
286
320
|
### Static Site
|
|
287
321
|
|
|
288
322
|
AWS S3 + Cloudfront static site.
|
|
@@ -467,4 +501,3 @@ const project = new studion.Project('demo-project', {
|
|
|
467
501
|
|
|
468
502
|
- [ ] Add worker service for executing tasks
|
|
469
503
|
- [ ] Add MongoDB service
|
|
470
|
-
- [ ] Make db username & password fields optional and autogenerate db username & password if they are not provided
|
|
@@ -10,14 +10,15 @@ export type DatabaseArgs = {
|
|
|
10
10
|
* Username for the master DB user.
|
|
11
11
|
*/
|
|
12
12
|
username: pulumi.Input<string>;
|
|
13
|
-
/**
|
|
14
|
-
* Password for the master DB user.
|
|
15
|
-
*/
|
|
16
|
-
password: pulumi.Input<string>;
|
|
17
13
|
/**
|
|
18
14
|
* The awsx.ec2.Vpc resource.
|
|
19
15
|
*/
|
|
20
16
|
vpc: awsx.ec2.Vpc;
|
|
17
|
+
/**
|
|
18
|
+
* Password for the master DB user. If not specified, it will be autogenerated.
|
|
19
|
+
* The value will be stored as a secret in AWS Secret Manager.
|
|
20
|
+
*/
|
|
21
|
+
password?: pulumi.Input<string>;
|
|
21
22
|
/**
|
|
22
23
|
* Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default is false.
|
|
23
24
|
*/
|
|
@@ -50,5 +51,6 @@ export declare class Database extends pulumi.ComponentResource {
|
|
|
50
51
|
kms: aws.kms.Key;
|
|
51
52
|
dbSubnetGroup: aws.rds.SubnetGroup;
|
|
52
53
|
dbSecurityGroup: aws.ec2.SecurityGroup;
|
|
54
|
+
passwordSecret: aws.secretsmanager.Secret;
|
|
53
55
|
constructor(name: string, args: DatabaseArgs, opts?: pulumi.ComponentResourceOptions);
|
|
54
56
|
}
|
|
@@ -13,6 +13,8 @@ const defaults = {
|
|
|
13
13
|
class Database extends pulumi.ComponentResource {
|
|
14
14
|
constructor(name, args, opts = {}) {
|
|
15
15
|
super('studion:Database', name, {}, opts);
|
|
16
|
+
const project = pulumi.getProject();
|
|
17
|
+
const stack = pulumi.getStack();
|
|
16
18
|
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
17
19
|
this.dbSubnetGroup = new aws.rds.SubnetGroup(`${name}-subnet-group`, {
|
|
18
20
|
subnetIds: argsWithDefaults.vpc.privateSubnetIds,
|
|
@@ -36,6 +38,17 @@ class Database extends pulumi.ComponentResource {
|
|
|
36
38
|
multiRegion: false,
|
|
37
39
|
enableKeyRotation: true,
|
|
38
40
|
}, { parent: this });
|
|
41
|
+
const password = argsWithDefaults.password ||
|
|
42
|
+
aws.secretsmanager
|
|
43
|
+
.getRandomPasswordOutput()
|
|
44
|
+
.apply(res => res.randomPassword);
|
|
45
|
+
this.passwordSecret = new aws.secretsmanager.Secret(`${name}-password-secret`, {
|
|
46
|
+
name: `${stack}/${project}/DatabasePassword`,
|
|
47
|
+
}, { parent: this });
|
|
48
|
+
const passwordSecretValue = new aws.secretsmanager.SecretVersion(`${name}-password-secret-value`, {
|
|
49
|
+
secretId: this.passwordSecret.id,
|
|
50
|
+
secretString: password,
|
|
51
|
+
}, { parent: this, dependsOn: [this.passwordSecret] });
|
|
39
52
|
this.instance = new aws.rds.Instance(`${name}-rds`, {
|
|
40
53
|
identifier: name,
|
|
41
54
|
engine: 'postgres',
|
|
@@ -45,7 +58,7 @@ class Database extends pulumi.ComponentResource {
|
|
|
45
58
|
instanceClass: argsWithDefaults.instanceClass,
|
|
46
59
|
dbName: argsWithDefaults.dbName,
|
|
47
60
|
username: argsWithDefaults.username,
|
|
48
|
-
password
|
|
61
|
+
password,
|
|
49
62
|
dbSubnetGroupName: this.dbSubnetGroup.name,
|
|
50
63
|
vpcSecurityGroupIds: [this.dbSecurityGroup.id],
|
|
51
64
|
storageEncrypted: true,
|
|
@@ -27,7 +27,8 @@ export type StaticSiteService = {
|
|
|
27
27
|
export type WebServerService = {
|
|
28
28
|
type: 'WEB_SERVER';
|
|
29
29
|
environment?: aws.ecs.KeyValuePair[] | ((services: Services) => aws.ecs.KeyValuePair[]);
|
|
30
|
-
|
|
30
|
+
secrets?: aws.ecs.Secret[] | ((services: Services) => aws.ecs.Secret[]);
|
|
31
|
+
} & ServiceArgs & Omit<WebServerArgs, 'cluster' | 'vpc' | 'hostedZoneId' | 'environment' | 'secrets'>;
|
|
31
32
|
export type ProjectArgs = {
|
|
32
33
|
services: (DatabaseService | RedisService | StaticSiteService | WebServerService)[];
|
|
33
34
|
hostedZoneId?: pulumi.Input<string>;
|
|
@@ -110,11 +110,12 @@ class Project extends pulumi.ComponentResource {
|
|
|
110
110
|
return;
|
|
111
111
|
if (!this.hostedZoneId)
|
|
112
112
|
throw new MissingHostedZoneId(options.type);
|
|
113
|
-
const { serviceName, environment } = options, ecsOptions = __rest(options, ["serviceName", "environment"]);
|
|
113
|
+
const { serviceName, environment, secrets } = options, ecsOptions = __rest(options, ["serviceName", "environment", "secrets"]);
|
|
114
114
|
const parsedEnv = typeof environment === 'function'
|
|
115
115
|
? environment(this.services)
|
|
116
116
|
: environment;
|
|
117
|
-
const
|
|
117
|
+
const parsedSecrets = typeof secrets === 'function' ? secrets(this.services) : secrets;
|
|
118
|
+
const service = new web_server_1.WebServer(serviceName, Object.assign(Object.assign({}, ecsOptions), { cluster: this.cluster, vpc: this.vpc, hostedZoneId: this.hostedZoneId, environment: parsedEnv, secrets: parsedSecrets }), { parent: this });
|
|
118
119
|
this.services[options.serviceName] = service;
|
|
119
120
|
}
|
|
120
121
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as pulumi from '@pulumi/pulumi';
|
|
2
2
|
import * as upstash from '@upstash/pulumi';
|
|
3
|
+
import * as aws from '@pulumi/aws';
|
|
3
4
|
export type RedisArgs = {
|
|
4
5
|
/**
|
|
5
6
|
* Redis database name.
|
|
@@ -15,5 +16,7 @@ export interface RedisOptions extends pulumi.ComponentResourceOptions {
|
|
|
15
16
|
}
|
|
16
17
|
export declare class Redis extends pulumi.ComponentResource {
|
|
17
18
|
instance: upstash.RedisDatabase;
|
|
19
|
+
passwordSecret: aws.secretsmanager.Secret;
|
|
20
|
+
username: string;
|
|
18
21
|
constructor(name: string, args: RedisArgs, opts: RedisOptions);
|
|
19
22
|
}
|
package/dist/components/redis.js
CHANGED
|
@@ -3,12 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Redis = void 0;
|
|
4
4
|
const pulumi = require("@pulumi/pulumi");
|
|
5
5
|
const upstash = require("@upstash/pulumi");
|
|
6
|
+
const aws = require("@pulumi/aws");
|
|
6
7
|
const defaults = {
|
|
7
8
|
region: 'us-east-1',
|
|
8
9
|
};
|
|
9
10
|
class Redis extends pulumi.ComponentResource {
|
|
10
11
|
constructor(name, args, opts) {
|
|
11
12
|
super('studion:Redis', name, {}, opts);
|
|
13
|
+
this.username = 'default';
|
|
14
|
+
const project = pulumi.getProject();
|
|
15
|
+
const stack = pulumi.getStack();
|
|
12
16
|
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
13
17
|
this.instance = new upstash.RedisDatabase(name, {
|
|
14
18
|
databaseName: argsWithDefaults.dbName,
|
|
@@ -16,6 +20,13 @@ class Redis extends pulumi.ComponentResource {
|
|
|
16
20
|
eviction: true,
|
|
17
21
|
tls: true,
|
|
18
22
|
}, { provider: opts.provider, parent: this });
|
|
23
|
+
this.passwordSecret = new aws.secretsmanager.Secret(`${name}-password-secret`, {
|
|
24
|
+
name: `${stack}/${project}/RedisPassword`,
|
|
25
|
+
}, { parent: this, dependsOn: [this.instance] });
|
|
26
|
+
const passwordSecretValue = new aws.secretsmanager.SecretVersion(`${name}-password-secret-value`, {
|
|
27
|
+
secretId: this.passwordSecret.id,
|
|
28
|
+
secretString: this.instance.password,
|
|
29
|
+
}, { parent: this, dependsOn: [this.passwordSecret] });
|
|
19
30
|
this.registerOutputs();
|
|
20
31
|
}
|
|
21
32
|
}
|
|
@@ -12,7 +12,6 @@ class StaticSite extends pulumi.ComponentResource {
|
|
|
12
12
|
hostedZoneId: args.hostedZoneId,
|
|
13
13
|
}, { parent: this });
|
|
14
14
|
const bucket = new aws.s3.Bucket(`${name}-bucket`, {
|
|
15
|
-
bucket: name,
|
|
16
15
|
website: {
|
|
17
16
|
indexDocument: 'index.html',
|
|
18
17
|
errorDocument: 'index.html',
|