Skip to content

Commit a007ba6

Browse files
committed
Create password resource
1 parent d1ed0d3 commit a007ba6

File tree

4 files changed

+90
-86
lines changed

4 files changed

+90
-86
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ type DatabaseArgs = {
372372

373373
If the password is not specified it will be autogenerated.
374374
The database password is stored as a secret inside AWS Secret Manager.
375-
The secret will be available on the `Database` resource as `passwordSecret`.
375+
The secret will be available on the `Database` resource as `password.secret`.
376376

377377
### Redis
378378

@@ -600,7 +600,7 @@ export type MongoArgs = {
600600

601601
If the password is not specified it will be autogenerated.
602602
The mongo password is stored as a secret inside AWS Secret Manager.
603-
The secret will be available on the `Mongo` resource as `passwordSecret`.
603+
The secret will be available on the `Mongo` resource as `password.secret`.
604604

605605
### Ecs Service
606606

src/components/database.ts

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as aws from '@pulumi/aws';
22
import * as pulumi from '@pulumi/pulumi';
3-
import * as random from '@pulumi/random';
3+
import { Password } from './password';
44
import { commonTags } from '../constants';
55

66
export type DatabaseArgs = {
@@ -68,7 +68,7 @@ export class Database extends pulumi.ComponentResource {
6868
kms: aws.kms.Key;
6969
dbSubnetGroup: aws.rds.SubnetGroup;
7070
dbSecurityGroup: aws.ec2.SecurityGroup;
71-
passwordSecret: aws.secretsmanager.Secret;
71+
password: Password;
7272

7373
constructor(
7474
name: string,
@@ -83,9 +83,12 @@ export class Database extends pulumi.ComponentResource {
8383
this.dbSubnetGroup = this.createSubnetGroup({ isolatedSubnetIds });
8484
this.dbSecurityGroup = this.createSecurityGroup({ vpcId, vpcCidrBlock });
8585
this.kms = this.createEncryptionKey();
86-
const { instance, passwordSecret } = this.createDatabaseInstance(args);
87-
this.instance = instance;
88-
this.passwordSecret = passwordSecret;
86+
this.password = new Password(
87+
`${this.name}-database-password`,
88+
{ value: args.password },
89+
{ parent: this },
90+
);
91+
this.instance = this.createDatabaseInstance(args);
8992

9093
this.registerOutputs();
9194
}
@@ -144,43 +147,9 @@ export class Database extends pulumi.ComponentResource {
144147
return kms;
145148
}
146149

147-
private createPasswordSecret({ password }: Pick<DatabaseArgs, 'password'>) {
148-
const project = pulumi.getProject();
149-
const stack = pulumi.getStack();
150-
151-
const passwordSecret = new aws.secretsmanager.Secret(
152-
`${this.name}-password-secret`,
153-
{
154-
namePrefix: `${stack}/${project}/DatabasePassword-`,
155-
tags: commonTags,
156-
},
157-
{ parent: this },
158-
);
159-
160-
const passwordSecretValue = new aws.secretsmanager.SecretVersion(
161-
`${this.name}-password-secret-value`,
162-
{
163-
secretId: passwordSecret.id,
164-
secretString: password,
165-
},
166-
{ parent: this, dependsOn: [passwordSecret] },
167-
);
168-
169-
return passwordSecret;
170-
}
171-
172150
private createDatabaseInstance(args: DatabaseArgs) {
173151
const argsWithDefaults = Object.assign({}, defaults, args);
174152
const stack = pulumi.getStack();
175-
const password =
176-
argsWithDefaults.password ||
177-
new random.RandomPassword(`${this.name}-db-password`, {
178-
length: 16,
179-
overrideSpecial: '_%$',
180-
special: true,
181-
}).result;
182-
183-
const passwordSecret = this.createPasswordSecret({ password });
184153

185154
const instance = new aws.rds.Instance(
186155
`${this.name}-rds`,
@@ -193,7 +162,7 @@ export class Database extends pulumi.ComponentResource {
193162
instanceClass: argsWithDefaults.instanceClass,
194163
dbName: argsWithDefaults.dbName,
195164
username: argsWithDefaults.username,
196-
password,
165+
password: this.password.value,
197166
dbSubnetGroupName: this.dbSubnetGroup.name,
198167
vpcSecurityGroupIds: [this.dbSecurityGroup.id],
199168
storageEncrypted: true,
@@ -208,8 +177,8 @@ export class Database extends pulumi.ComponentResource {
208177
backupRetentionPeriod: 14,
209178
tags: { ...commonTags, ...argsWithDefaults.tags },
210179
},
211-
{ parent: this },
180+
{ parent: this, dependsOn: [this.password] },
212181
);
213-
return { instance, passwordSecret };
182+
return instance;
214183
}
215184
}

src/components/mongo.ts

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import * as pulumi from '@pulumi/pulumi';
2-
import * as aws from '@pulumi/aws';
3-
import * as random from '@pulumi/random';
4-
import { commonTags } from '../constants';
52
import { EcsService, EcsServiceArgs } from './ecs-service';
3+
import { Password } from './password';
64

75
export type MongoArgs = Pick<
86
EcsServiceArgs,
@@ -27,7 +25,7 @@ export type MongoArgs = Pick<
2725
export class Mongo extends pulumi.ComponentResource {
2826
name: string;
2927
service: EcsService;
30-
passwordSecret: aws.secretsmanager.Secret;
28+
password: Password;
3129

3230
constructor(
3331
name: string,
@@ -42,8 +40,11 @@ export class Mongo extends pulumi.ComponentResource {
4240

4341
this.name = name;
4442

45-
const mongoPassword = password || this.createRandomPassword();
46-
this.passwordSecret = this.createPasswordSecret(mongoPassword);
43+
this.password = new Password(
44+
`${this.name}-mongo-password`,
45+
{ value: password },
46+
{ parent: this },
47+
);
4748

4849
this.service = new EcsService(
4950
name,
@@ -68,7 +69,7 @@ export class Mongo extends pulumi.ComponentResource {
6869
secrets: [
6970
{
7071
name: 'MONGO_INITDB_ROOT_PASSWORD',
71-
valueFrom: this.passwordSecret.arn,
72+
valueFrom: this.password.secret.arn,
7273
},
7374
],
7475
},
@@ -77,39 +78,4 @@ export class Mongo extends pulumi.ComponentResource {
7778

7879
this.registerOutputs();
7980
}
80-
81-
private createRandomPassword() {
82-
const password = new random.RandomPassword(`${this.name}-mongo-password`, {
83-
length: 16,
84-
overrideSpecial: '_%$',
85-
special: true,
86-
});
87-
88-
return password.result;
89-
}
90-
91-
private createPasswordSecret(password: MongoArgs['password']) {
92-
const project = pulumi.getProject();
93-
const stack = pulumi.getStack();
94-
95-
const passwordSecret = new aws.secretsmanager.Secret(
96-
`${this.name}-password-secret`,
97-
{
98-
namePrefix: `${stack}/${project}/MongoPassword-`,
99-
tags: commonTags,
100-
},
101-
{ parent: this },
102-
);
103-
104-
const passwordSecretValue = new aws.secretsmanager.SecretVersion(
105-
`${this.name}-password-secret-value`,
106-
{
107-
secretId: passwordSecret.id,
108-
secretString: password,
109-
},
110-
{ parent: this, dependsOn: [passwordSecret] },
111-
);
112-
113-
return passwordSecret;
114-
}
11581
}

src/components/password.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import * as aws from '@pulumi/aws';
2+
import * as pulumi from '@pulumi/pulumi';
3+
import * as random from '@pulumi/random';
4+
import { commonTags } from '../constants';
5+
6+
export type PasswordArgs = {
7+
value?: pulumi.Input<string>;
8+
};
9+
10+
export class Password extends pulumi.ComponentResource {
11+
name: string;
12+
value: pulumi.Output<string>;
13+
secret: aws.secretsmanager.Secret;
14+
15+
constructor(
16+
name: string,
17+
args: PasswordArgs,
18+
opts: pulumi.ComponentResourceOptions = {},
19+
) {
20+
const optsWithDefauls = pulumi.mergeOptions(opts, {
21+
additionalSecretOutputs: ['value'],
22+
});
23+
super('studion:Password', name, {}, optsWithDefauls);
24+
25+
this.name = name;
26+
if (args.value) {
27+
this.value = pulumi.output(args.value);
28+
} else {
29+
const password = new random.RandomPassword(
30+
`${this.name}-random-password`,
31+
{
32+
length: 16,
33+
overrideSpecial: '_%$',
34+
special: true,
35+
},
36+
{ parent: this },
37+
);
38+
this.value = password.result;
39+
}
40+
41+
this.secret = this.createPasswordSecret(this.value);
42+
this.registerOutputs();
43+
}
44+
45+
private createPasswordSecret(password: pulumi.Input<string>) {
46+
const project = pulumi.getProject();
47+
const stack = pulumi.getStack();
48+
49+
const passwordSecret = new aws.secretsmanager.Secret(
50+
`${this.name}-password-secret`,
51+
{
52+
namePrefix: `${stack}/${project}/${this.name}-`,
53+
tags: commonTags,
54+
},
55+
{ parent: this },
56+
);
57+
58+
const passwordSecretValue = new aws.secretsmanager.SecretVersion(
59+
`${this.name}-password-secret-value`,
60+
{
61+
secretId: passwordSecret.id,
62+
secretString: password,
63+
},
64+
{ parent: this, dependsOn: [passwordSecret] },
65+
);
66+
67+
return passwordSecret;
68+
}
69+
}

0 commit comments

Comments
 (0)