@studion/infra-code-blocks 0.1.8 → 0.1.9
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 +22 -9
- package/dist/components/database.d.ts +5 -5
- package/dist/components/database.js +15 -6
- package/dist/components/ec2-ssm-connect.js +12 -1
- package/dist/components/project.js +0 -2
- package/dist/components/static-site.d.ts +3 -3
- package/dist/components/static-site.js +22 -23
- package/dist/constants.d.ts +0 -5
- package/dist/constants.js +1 -6
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,9 +4,15 @@ Studion Platform common infra components.
|
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
|
-
1. [
|
|
8
|
-
2. [
|
|
9
|
-
3. [
|
|
7
|
+
1. [Prerequisites](#prerequisites)
|
|
8
|
+
2. [Installation](#installation)
|
|
9
|
+
3. [Usage](#usage)
|
|
10
|
+
4. [API](#api)
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- Working [Pulumi](https://www.pulumi.com/docs/clouds/aws/get-started/begin/#pulumi-aws-before-you-begin) project
|
|
15
|
+
- AWS account with neccessary permissions for each studion component
|
|
10
16
|
|
|
11
17
|
## Installation
|
|
12
18
|
|
|
@@ -42,6 +48,12 @@ const project = new studion.Project('demo-project', {
|
|
|
42
48
|
export const projectName = project.name;
|
|
43
49
|
```
|
|
44
50
|
|
|
51
|
+
- Deploy pulumi stack
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
$ pulumi up
|
|
55
|
+
```
|
|
56
|
+
|
|
45
57
|
## API
|
|
46
58
|
|
|
47
59
|
1. [Project](#project)
|
|
@@ -83,7 +95,7 @@ type ProjectArgs = {
|
|
|
83
95
|
| Argument | Description |
|
|
84
96
|
| :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
85
97
|
| services \* | Service list. |
|
|
86
|
-
| hostedZoneId |
|
|
98
|
+
| hostedZoneId | Route53 hosted zone ID responsible for managing records for the domain. Required for 'STATIC_SITE' and 'WEB_SERVER' |
|
|
87
99
|
| enableSSMConnect | Setup ec2 instance and SSM in order to connect to the database in the private subnet. Please refer to the [SSM Connect](#ssm-connect) section for more info. |
|
|
88
100
|
|
|
89
101
|
```ts
|
|
@@ -92,7 +104,7 @@ type DatabaseService = {
|
|
|
92
104
|
serviceName: string;
|
|
93
105
|
dbName: pulumi.Input<string>;
|
|
94
106
|
username: pulumi.Input<string>;
|
|
95
|
-
password
|
|
107
|
+
password?: pulumi.Input<string>;
|
|
96
108
|
applyImmediately?: pulumi.Input<boolean>;
|
|
97
109
|
skipFinalSnapshot?: pulumi.Input<boolean>;
|
|
98
110
|
allocatedStorage?: pulumi.Input<number>;
|
|
@@ -117,7 +129,7 @@ export type RedisService = {
|
|
|
117
129
|
export type StaticSiteService = {
|
|
118
130
|
type: 'STATIC_SITE';
|
|
119
131
|
serviceName: string;
|
|
120
|
-
domain
|
|
132
|
+
domain?: pulumi.Input<string>;
|
|
121
133
|
tags?: pulumi.Input<{
|
|
122
134
|
[key: string]: pulumi.Input<string>;
|
|
123
135
|
}>;
|
|
@@ -256,8 +268,8 @@ new Database(name: string, args: DatabaseArgs, opts?: pulumi.CustomResourceOptio
|
|
|
256
268
|
type DatabaseArgs = {
|
|
257
269
|
dbName: pulumi.Input<string>;
|
|
258
270
|
username: pulumi.Input<string>;
|
|
259
|
-
password: pulumi.Input<string>;
|
|
260
271
|
vpc: awsx.ec2.Vpc;
|
|
272
|
+
password?: pulumi.Input<string>;
|
|
261
273
|
applyImmediately?: pulumi.Input<boolean>;
|
|
262
274
|
skipFinalSnapshot?: pulumi.Input<boolean>;
|
|
263
275
|
allocatedStorage?: pulumi.Input<number>;
|
|
@@ -269,6 +281,7 @@ type DatabaseArgs = {
|
|
|
269
281
|
};
|
|
270
282
|
```
|
|
271
283
|
|
|
284
|
+
If the password is not specified it will be autogenerated.
|
|
272
285
|
The database password is stored as a secret inside AWS Secret Manager.
|
|
273
286
|
The secret will be available on the `Database` resource as `passwordSecret`.
|
|
274
287
|
|
|
@@ -341,8 +354,8 @@ new StaticSite(name: string, args: StaticSiteArgs, opts?: pulumi.ComponentResour
|
|
|
341
354
|
|
|
342
355
|
```ts
|
|
343
356
|
type StaticSiteArgs = {
|
|
344
|
-
domain
|
|
345
|
-
hostedZoneId
|
|
357
|
+
domain?: pulumi.Input<string>;
|
|
358
|
+
hostedZoneId?: pulumi.Input<string>;
|
|
346
359
|
tags?: pulumi.Input<{
|
|
347
360
|
[key: string]: pulumi.Input<string>;
|
|
348
361
|
}>;
|
|
@@ -10,15 +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
|
-
* The value will be stored as a secret in AWS Secret Manager.
|
|
16
|
-
*/
|
|
17
|
-
password: pulumi.Input<string>;
|
|
18
13
|
/**
|
|
19
14
|
* The awsx.ec2.Vpc resource.
|
|
20
15
|
*/
|
|
21
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>;
|
|
22
22
|
/**
|
|
23
23
|
* Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default is false.
|
|
24
24
|
*/
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Database = void 0;
|
|
4
4
|
const aws = require("@pulumi/aws");
|
|
5
5
|
const pulumi = require("@pulumi/pulumi");
|
|
6
|
+
const random = require("@pulumi/random");
|
|
6
7
|
const constants_1 = require("../constants");
|
|
7
8
|
const defaults = {
|
|
8
9
|
applyImmediately: false,
|
|
@@ -15,12 +16,13 @@ class Database extends pulumi.ComponentResource {
|
|
|
15
16
|
constructor(name, args, opts = {}) {
|
|
16
17
|
super('studion:Database', name, {}, opts);
|
|
17
18
|
this.name = name;
|
|
18
|
-
const { vpc
|
|
19
|
+
const { vpc } = args;
|
|
19
20
|
this.dbSubnetGroup = this.createSubnetGroup({ vpc });
|
|
20
21
|
this.dbSecurityGroup = this.createSecurityGroup({ vpc });
|
|
21
22
|
this.kms = this.createEncryptionKey();
|
|
22
|
-
|
|
23
|
-
this.instance =
|
|
23
|
+
const { instance, passwordSecret } = this.createDatabaseInstance(args);
|
|
24
|
+
this.instance = instance;
|
|
25
|
+
this.passwordSecret = passwordSecret;
|
|
24
26
|
this.registerOutputs();
|
|
25
27
|
}
|
|
26
28
|
createSubnetGroup({ vpc }) {
|
|
@@ -73,16 +75,23 @@ class Database extends pulumi.ComponentResource {
|
|
|
73
75
|
createDatabaseInstance(args) {
|
|
74
76
|
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
75
77
|
const stack = pulumi.getStack();
|
|
78
|
+
const password = argsWithDefaults.password ||
|
|
79
|
+
new random.RandomPassword(`${this.name}-db-password`, {
|
|
80
|
+
length: 16,
|
|
81
|
+
overrideSpecial: '_%$',
|
|
82
|
+
special: true,
|
|
83
|
+
}).result;
|
|
84
|
+
const passwordSecret = this.createPasswordSecret({ password });
|
|
76
85
|
const instance = new aws.rds.Instance(`${this.name}-rds`, {
|
|
77
86
|
identifierPrefix: `${this.name}-`,
|
|
78
87
|
engine: 'postgres',
|
|
79
|
-
engineVersion: '
|
|
88
|
+
engineVersion: '15.3',
|
|
80
89
|
allocatedStorage: argsWithDefaults.allocatedStorage,
|
|
81
90
|
maxAllocatedStorage: argsWithDefaults.maxAllocatedStorage,
|
|
82
91
|
instanceClass: argsWithDefaults.instanceClass,
|
|
83
92
|
dbName: argsWithDefaults.dbName,
|
|
84
93
|
username: argsWithDefaults.username,
|
|
85
|
-
password
|
|
94
|
+
password,
|
|
86
95
|
dbSubnetGroupName: this.dbSubnetGroup.name,
|
|
87
96
|
vpcSecurityGroupIds: [this.dbSecurityGroup.id],
|
|
88
97
|
storageEncrypted: true,
|
|
@@ -97,7 +106,7 @@ class Database extends pulumi.ComponentResource {
|
|
|
97
106
|
backupRetentionPeriod: 14,
|
|
98
107
|
tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags),
|
|
99
108
|
}, { parent: this });
|
|
100
|
-
return instance;
|
|
109
|
+
return { instance, passwordSecret };
|
|
101
110
|
}
|
|
102
111
|
}
|
|
103
112
|
exports.Database = Database;
|
|
@@ -6,6 +6,17 @@ const aws = require("@pulumi/aws");
|
|
|
6
6
|
const constants_1 = require("../constants");
|
|
7
7
|
const config = new pulumi.Config('aws');
|
|
8
8
|
const awsRegion = config.require('region');
|
|
9
|
+
const AmazonLinux2023_ARM_EC2_AMI = aws.ec2.getAmiOutput({
|
|
10
|
+
filters: [
|
|
11
|
+
{ name: 'architecture', values: ['arm64'] },
|
|
12
|
+
{ name: 'root-device-type', values: ['ebs'] },
|
|
13
|
+
{ name: 'virtualization-type', values: ['hvm'] },
|
|
14
|
+
{ name: 'ena-support', values: ['true'] },
|
|
15
|
+
],
|
|
16
|
+
owners: ['amazon'],
|
|
17
|
+
nameRegex: 'al2023-ami-2023.2.20231030.1-kernel-6.1-arm64',
|
|
18
|
+
mostRecent: true,
|
|
19
|
+
});
|
|
9
20
|
class Ec2SSMConnect extends pulumi.ComponentResource {
|
|
10
21
|
constructor(name, args, opts = {}) {
|
|
11
22
|
super('studion:Ec2BastionSSMConnect', name, {}, opts);
|
|
@@ -55,7 +66,7 @@ class Ec2SSMConnect extends pulumi.ComponentResource {
|
|
|
55
66
|
tags: constants_1.commonTags,
|
|
56
67
|
}, { parent: this, dependsOn: [ssmPolicyAttachment] });
|
|
57
68
|
this.ec2 = new aws.ec2.Instance(`${name}-ec2`, {
|
|
58
|
-
ami:
|
|
69
|
+
ami: AmazonLinux2023_ARM_EC2_AMI.id,
|
|
59
70
|
associatePublicIpAddress: false,
|
|
60
71
|
instanceType: 't4g.nano',
|
|
61
72
|
iamInstanceProfile: ssmProfile.name,
|
|
@@ -109,8 +109,6 @@ class Project extends pulumi.ComponentResource {
|
|
|
109
109
|
}
|
|
110
110
|
createStaticSiteService(options) {
|
|
111
111
|
const { serviceName } = options, staticSiteOptions = __rest(options, ["serviceName"]);
|
|
112
|
-
if (!this.hostedZoneId)
|
|
113
|
-
throw new MissingHostedZoneId(options.type);
|
|
114
112
|
const service = new static_site_1.StaticSite(serviceName, Object.assign(Object.assign({}, staticSiteOptions), { hostedZoneId: this.hostedZoneId }), { parent: this });
|
|
115
113
|
this.services[serviceName] = service;
|
|
116
114
|
}
|
|
@@ -6,11 +6,11 @@ export type StaticSiteArgs = {
|
|
|
6
6
|
* The domain which will be used to access the static site.
|
|
7
7
|
* The domain or subdomain must belong to the provided hostedZone.
|
|
8
8
|
*/
|
|
9
|
-
domain
|
|
9
|
+
domain?: pulumi.Input<string>;
|
|
10
10
|
/**
|
|
11
11
|
* The ID of the hosted zone.
|
|
12
12
|
*/
|
|
13
|
-
hostedZoneId
|
|
13
|
+
hostedZoneId?: pulumi.Input<string>;
|
|
14
14
|
/**
|
|
15
15
|
* A map of tags to assign to the resource.
|
|
16
16
|
*/
|
|
@@ -20,7 +20,7 @@ export type StaticSiteArgs = {
|
|
|
20
20
|
};
|
|
21
21
|
export declare class StaticSite extends pulumi.ComponentResource {
|
|
22
22
|
name: string;
|
|
23
|
-
certificate
|
|
23
|
+
certificate?: AcmCertificate;
|
|
24
24
|
bucket: aws.s3.Bucket;
|
|
25
25
|
cloudfront: aws.cloudfront.Distribution;
|
|
26
26
|
constructor(name: string, args: StaticSiteArgs, opts?: pulumi.ComponentResourceOptions);
|
|
@@ -10,10 +10,18 @@ class StaticSite extends pulumi.ComponentResource {
|
|
|
10
10
|
super('studion:StaticSite', name, {}, opts);
|
|
11
11
|
this.name = name;
|
|
12
12
|
const { domain, hostedZoneId, tags } = args;
|
|
13
|
-
|
|
13
|
+
const hasCustomDomain = domain && hostedZoneId;
|
|
14
|
+
if (domain && !hostedZoneId) {
|
|
15
|
+
throw new Error('StaticSite:hostedZoneId must be provided when the domain is specified');
|
|
16
|
+
}
|
|
17
|
+
if (hasCustomDomain) {
|
|
18
|
+
this.certificate = this.createTlsCertificate({ domain, hostedZoneId });
|
|
19
|
+
}
|
|
14
20
|
this.bucket = this.createPublicBucket({ tags });
|
|
15
21
|
this.cloudfront = this.createCloudfrontDistribution({ domain, tags });
|
|
16
|
-
|
|
22
|
+
if (hasCustomDomain) {
|
|
23
|
+
this.createDnsRecord({ domain, hostedZoneId });
|
|
24
|
+
}
|
|
17
25
|
this.registerOutputs();
|
|
18
26
|
}
|
|
19
27
|
createTlsCertificate({ domain, hostedZoneId, }) {
|
|
@@ -59,19 +67,15 @@ class StaticSite extends pulumi.ComponentResource {
|
|
|
59
67
|
return bucket;
|
|
60
68
|
}
|
|
61
69
|
createCloudfrontDistribution({ domain, tags, }) {
|
|
62
|
-
const cloudfront = new aws.cloudfront.Distribution(`${this.name}-cloudfront`, {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
sslSupportMethod: 'sni-only',
|
|
72
|
-
minimumProtocolVersion: 'TLSv1.2_2021',
|
|
73
|
-
},
|
|
74
|
-
origins: [
|
|
70
|
+
const cloudfront = new aws.cloudfront.Distribution(`${this.name}-cloudfront`, Object.assign(Object.assign({ enabled: true, defaultRootObject: 'index.html' }, (domain && { aliases: [domain] })), { isIpv6Enabled: true, waitForDeployment: true, httpVersion: 'http2and3', viewerCertificate: Object.assign({}, (this.certificate
|
|
71
|
+
? {
|
|
72
|
+
acmCertificateArn: this.certificate.certificate.arn,
|
|
73
|
+
sslSupportMethod: 'sni-only',
|
|
74
|
+
minimumProtocolVersion: 'TLSv1.2_2021',
|
|
75
|
+
}
|
|
76
|
+
: {
|
|
77
|
+
cloudfrontDefaultCertificate: true,
|
|
78
|
+
})), origins: [
|
|
75
79
|
{
|
|
76
80
|
originId: this.bucket.arn,
|
|
77
81
|
domainName: this.bucket.websiteEndpoint,
|
|
@@ -84,8 +88,7 @@ class StaticSite extends pulumi.ComponentResource {
|
|
|
84
88
|
originSslProtocols: ['TLSv1.2'],
|
|
85
89
|
},
|
|
86
90
|
},
|
|
87
|
-
],
|
|
88
|
-
defaultCacheBehavior: {
|
|
91
|
+
], defaultCacheBehavior: {
|
|
89
92
|
targetOriginId: this.bucket.arn,
|
|
90
93
|
viewerProtocolPolicy: 'redirect-to-https',
|
|
91
94
|
allowedMethods: ['GET', 'HEAD', 'OPTIONS'],
|
|
@@ -98,13 +101,9 @@ class StaticSite extends pulumi.ComponentResource {
|
|
|
98
101
|
cookies: { forward: 'none' },
|
|
99
102
|
queryString: false,
|
|
100
103
|
},
|
|
101
|
-
},
|
|
102
|
-
priceClass: 'PriceClass_100',
|
|
103
|
-
restrictions: {
|
|
104
|
+
}, priceClass: 'PriceClass_100', restrictions: {
|
|
104
105
|
geoRestriction: { restrictionType: 'none' },
|
|
105
|
-
},
|
|
106
|
-
tags: Object.assign(Object.assign({}, constants_1.commonTags), tags),
|
|
107
|
-
}, { parent: this });
|
|
106
|
+
}, tags: Object.assign(Object.assign({}, constants_1.commonTags), tags) }), { parent: this });
|
|
108
107
|
return cloudfront;
|
|
109
108
|
}
|
|
110
109
|
createDnsRecord({ domain, hostedZoneId, }) {
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.commonTags = exports.
|
|
3
|
+
exports.commonTags = exports.PredefinedSize = void 0;
|
|
4
4
|
const pulumi = require("@pulumi/pulumi");
|
|
5
5
|
const CPU_1_VCPU = 1024;
|
|
6
6
|
const MEMORY_1GB = 1024;
|
|
@@ -22,11 +22,6 @@ exports.PredefinedSize = {
|
|
|
22
22
|
memory: MEMORY_1GB * 4, // 4 GB memory
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
|
-
exports.Ec2AMI = {
|
|
26
|
-
AmazonLinux2023: {
|
|
27
|
-
ARM: 'ami-0b40baa8c6b882e6c',
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
25
|
exports.commonTags = {
|
|
31
26
|
Env: pulumi.getStack(),
|
|
32
27
|
Project: pulumi.getProject(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studion/infra-code-blocks",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Studion common infra components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"infrastructure",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"@pulumi/aws": "^5.0.0",
|
|
36
36
|
"@pulumi/awsx": "^1.0.0",
|
|
37
37
|
"@pulumi/pulumi": "^3.0.0",
|
|
38
|
+
"@pulumi/random": "^4.14.0",
|
|
38
39
|
"@upstash/pulumi": "^0.2.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|