@appliance.sh/infra 1.11.1 → 1.12.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appliance.sh/infra",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "Deploy the Appliance Infrastructure",
|
|
5
5
|
"repository": "https://github.com/appliance-sh/appliance.sh",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@pulumi/aws": "^7.15.0",
|
|
17
|
+
"@pulumi/aws-native": "^1.46.0",
|
|
17
18
|
"@pulumi/awsx": "^3.1.0",
|
|
18
19
|
"@pulumi/pulumi": "^3.213.0"
|
|
19
20
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as aws from '@pulumi/aws';
|
|
2
|
+
import * as awsNative from '@pulumi/aws-native';
|
|
2
3
|
import * as pulumi from '@pulumi/pulumi';
|
|
3
4
|
import { lookup } from './controller';
|
|
4
5
|
import { applianceBaseConfigInput } from '@appliance.sh/sdk';
|
|
@@ -27,10 +28,21 @@ export async function applianceInfra() {
|
|
|
27
28
|
|
|
28
29
|
const baseGlobalProvider = new aws.Provider(`${base}-global-provider`, { region: 'us-east-1' });
|
|
29
30
|
const baseRegionalProvider = new aws.Provider(`${base}-region-provider`, { region: baseConfig.data.region });
|
|
31
|
+
|
|
32
|
+
const baseNativeGlobalProvider = new awsNative.Provider(`${base}-native-global-provider`, { region: 'us-east-1' });
|
|
33
|
+
const baseNativeRegionalProvider = new awsNative.Provider(`${base}-native-region-provider`, {
|
|
34
|
+
region: baseConfig.data.region as awsNative.Region,
|
|
35
|
+
});
|
|
30
36
|
const applianceBase = new baseController(
|
|
31
37
|
`${base}`,
|
|
32
|
-
|
|
33
|
-
{
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
{ config: baseConfig.data as any },
|
|
40
|
+
{
|
|
41
|
+
globalProvider: baseGlobalProvider,
|
|
42
|
+
provider: baseRegionalProvider,
|
|
43
|
+
nativeProvider: baseNativeRegionalProvider,
|
|
44
|
+
nativeGlobalProvider: baseNativeGlobalProvider,
|
|
45
|
+
}
|
|
34
46
|
);
|
|
35
47
|
|
|
36
48
|
applianceBases.push(applianceBase);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as pulumi from '@pulumi/pulumi';
|
|
2
2
|
import * as aws from '@pulumi/aws';
|
|
3
|
+
import * as awsNative from '@pulumi/aws-native';
|
|
4
|
+
|
|
3
5
|
import { ApplianceBaseAwsPublicInput } from '@appliance.sh/sdk';
|
|
4
6
|
|
|
5
7
|
export type ApplianceBaseAwsPublicArgs = {
|
|
@@ -8,11 +10,17 @@ export type ApplianceBaseAwsPublicArgs = {
|
|
|
8
10
|
|
|
9
11
|
export interface ApplianceBaseAwsPublicOpts extends pulumi.ComponentResourceOptions {
|
|
10
12
|
globalProvider?: pulumi.ProviderResource;
|
|
13
|
+
nativeProvider?: pulumi.ProviderResource;
|
|
14
|
+
nativeGlobalProvider?: pulumi.ProviderResource;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
export class ApplianceBaseAwsPublic extends pulumi.ComponentResource {
|
|
14
|
-
public readonly zoneId
|
|
18
|
+
public readonly zoneId: pulumi.Output<string>;
|
|
15
19
|
public readonly zone?: aws.route53.Zone;
|
|
20
|
+
public readonly globalCert?: aws.acm.Certificate;
|
|
21
|
+
public readonly certificateArn?: pulumi.Output<string>;
|
|
22
|
+
public readonly cloudfrontDistribution?: aws.cloudfront.Distribution;
|
|
23
|
+
|
|
16
24
|
constructor(name: string, args: ApplianceBaseAwsPublicArgs, opts?: ApplianceBaseAwsPublicOpts) {
|
|
17
25
|
super('appliance-infra:appliance-base-aws-public', name, args, opts);
|
|
18
26
|
|
|
@@ -26,6 +34,195 @@ export class ApplianceBaseAwsPublic extends pulumi.ComponentResource {
|
|
|
26
34
|
);
|
|
27
35
|
|
|
28
36
|
this.zoneId = this.zone.zoneId;
|
|
37
|
+
} else {
|
|
38
|
+
this.zoneId = aws.route53.getZoneOutput({
|
|
39
|
+
name: args.config.dns.domainName,
|
|
40
|
+
}).id;
|
|
29
41
|
}
|
|
42
|
+
|
|
43
|
+
const wildcardDomain = `*.${args.config.dns.domainName}`;
|
|
44
|
+
const createCertificate = true;
|
|
45
|
+
if (createCertificate) {
|
|
46
|
+
this.globalCert = new aws.acm.Certificate(
|
|
47
|
+
`${name}-global-certificate`,
|
|
48
|
+
{
|
|
49
|
+
domainName: wildcardDomain,
|
|
50
|
+
subjectAlternativeNames: [wildcardDomain],
|
|
51
|
+
validationMethod: 'DNS',
|
|
52
|
+
region: 'us-east-1',
|
|
53
|
+
},
|
|
54
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const globalCertValidationRecords = this.globalCert.domainValidationOptions.apply((certValOpts) => {
|
|
58
|
+
return certValOpts.map((certValOpt, idx) => {
|
|
59
|
+
return new aws.route53.Record(
|
|
60
|
+
`${name}-global-cert-val-${idx}`,
|
|
61
|
+
{
|
|
62
|
+
zoneId: this.zoneId,
|
|
63
|
+
name: certValOpt.resourceRecordName,
|
|
64
|
+
type: certValOpt.resourceRecordType,
|
|
65
|
+
records: [certValOpt.resourceRecordValue],
|
|
66
|
+
ttl: 60,
|
|
67
|
+
},
|
|
68
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
new aws.acm.CertificateValidation(
|
|
74
|
+
`${name}-global-cert-validation`,
|
|
75
|
+
{
|
|
76
|
+
region: 'us-east-1',
|
|
77
|
+
validationRecordFqdns: globalCertValidationRecords.apply((records) => records.map((record) => record.fqdn)),
|
|
78
|
+
certificateArn: this.globalCert.arn,
|
|
79
|
+
},
|
|
80
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
this.certificateArn = this.globalCert.arn;
|
|
84
|
+
} else {
|
|
85
|
+
this.certificateArn = aws.acm.getCertificateOutput(
|
|
86
|
+
{
|
|
87
|
+
region: 'us-east-1',
|
|
88
|
+
domain: wildcardDomain,
|
|
89
|
+
},
|
|
90
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
91
|
+
).arn;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const lambdaOrigin = new aws.lambda.CallbackFunction(
|
|
95
|
+
`${name}-origin`,
|
|
96
|
+
{
|
|
97
|
+
name: `${name}-origin`.replaceAll('.', '-'),
|
|
98
|
+
runtime: 'nodejs22.x',
|
|
99
|
+
callback: async () => {
|
|
100
|
+
const result = {
|
|
101
|
+
message: 'Hello world!',
|
|
102
|
+
time: new Date().toISOString(),
|
|
103
|
+
};
|
|
104
|
+
return { statusCode: 200, body: JSON.stringify(result) };
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{ parent: this, provider: opts?.provider }
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const lambdaOriginFunctionUrl = new aws.lambda.FunctionUrl(
|
|
111
|
+
`${name}-origin-url`,
|
|
112
|
+
{
|
|
113
|
+
functionName: lambdaOrigin.name,
|
|
114
|
+
authorizationType: 'AWS_IAM',
|
|
115
|
+
invokeMode: 'BUFFERED',
|
|
116
|
+
cors: {
|
|
117
|
+
allowCredentials: true,
|
|
118
|
+
allowOrigins: [`https://api.${args.config.dns.domainName}`],
|
|
119
|
+
allowMethods: ['GET', 'POST'],
|
|
120
|
+
allowHeaders: ['date', 'keep-alive'],
|
|
121
|
+
exposeHeaders: ['keep-alive', 'date'],
|
|
122
|
+
maxAge: 60,
|
|
123
|
+
},
|
|
124
|
+
region: 'ap-southeast-1',
|
|
125
|
+
},
|
|
126
|
+
{ parent: this, provider: opts?.provider }
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const lambdaOac = new aws.cloudfront.OriginAccessControl(
|
|
130
|
+
`${name}-origin-access-control`,
|
|
131
|
+
{
|
|
132
|
+
name: 'MyLambdaOAC',
|
|
133
|
+
originAccessControlOriginType: 'lambda',
|
|
134
|
+
signingBehavior: 'always',
|
|
135
|
+
signingProtocol: 'sigv4',
|
|
136
|
+
},
|
|
137
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
this.cloudfrontDistribution = new aws.cloudfront.Distribution(
|
|
141
|
+
`${name}-distribution`,
|
|
142
|
+
{
|
|
143
|
+
defaultCacheBehavior: {
|
|
144
|
+
cachePolicyId: aws.cloudfront
|
|
145
|
+
.getCachePolicyOutput(
|
|
146
|
+
{ name: 'Managed-CachingDisabled' },
|
|
147
|
+
{
|
|
148
|
+
parent: this,
|
|
149
|
+
provider: opts?.globalProvider,
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
.apply((res) => res.id ?? ''),
|
|
153
|
+
originRequestPolicyId: aws.cloudfront
|
|
154
|
+
.getOriginRequestPolicyOutput(
|
|
155
|
+
{ name: 'Managed-AllViewerExceptHostHeader' },
|
|
156
|
+
{
|
|
157
|
+
parent: this,
|
|
158
|
+
provider: opts?.globalProvider,
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
.apply((res) => res.id ?? ''),
|
|
162
|
+
allowedMethods: ['HEAD', 'GET'],
|
|
163
|
+
cachedMethods: ['HEAD', 'GET'],
|
|
164
|
+
targetOriginId: 'LambdaOrigin',
|
|
165
|
+
viewerProtocolPolicy: 'redirect-to-https',
|
|
166
|
+
},
|
|
167
|
+
origins: [
|
|
168
|
+
{
|
|
169
|
+
originId: 'LambdaOrigin',
|
|
170
|
+
domainName: lambdaOriginFunctionUrl.functionUrl.apply((url) => new URL(url).hostname),
|
|
171
|
+
originAccessControlId: lambdaOac.id,
|
|
172
|
+
customOriginConfig: {
|
|
173
|
+
httpPort: 80,
|
|
174
|
+
httpsPort: 443,
|
|
175
|
+
originProtocolPolicy: 'https-only',
|
|
176
|
+
originSslProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
restrictions: { geoRestriction: { restrictionType: 'none' } },
|
|
181
|
+
viewerCertificate: {
|
|
182
|
+
acmCertificateArn: this.certificateArn,
|
|
183
|
+
sslSupportMethod: 'sni-only',
|
|
184
|
+
minimumProtocolVersion: 'TLSv1',
|
|
185
|
+
},
|
|
186
|
+
enabled: true,
|
|
187
|
+
aliases: [wildcardDomain],
|
|
188
|
+
},
|
|
189
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
new aws.lambda.Permission(
|
|
193
|
+
`${name.replaceAll('.', '-')}-origin-invoke-function-url-permission`,
|
|
194
|
+
{
|
|
195
|
+
action: 'lambda:InvokeFunctionUrl',
|
|
196
|
+
principal: 'cloudfront.amazonaws.com',
|
|
197
|
+
function: lambdaOrigin.name,
|
|
198
|
+
functionUrlAuthType: 'AWS_IAM',
|
|
199
|
+
sourceArn: this.cloudfrontDistribution.arn,
|
|
200
|
+
},
|
|
201
|
+
{ parent: this, provider: opts?.provider }
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
new awsNative.lambda.Permission(
|
|
205
|
+
`${name.replaceAll('.', '-')}-origin-invoke-function-permission`,
|
|
206
|
+
{
|
|
207
|
+
action: 'lambda:InvokeFunction',
|
|
208
|
+
principal: 'cloudfront.amazonaws.com',
|
|
209
|
+
sourceArn: this.cloudfrontDistribution.arn,
|
|
210
|
+
functionName: lambdaOrigin.name,
|
|
211
|
+
invokedViaFunctionUrl: true,
|
|
212
|
+
},
|
|
213
|
+
{ parent: this, provider: opts?.nativeProvider }
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
new aws.route53.Record(
|
|
217
|
+
`${name}-wildcard-cloudfront-record`,
|
|
218
|
+
{
|
|
219
|
+
name: wildcardDomain,
|
|
220
|
+
zoneId: this.zoneId,
|
|
221
|
+
type: 'CNAME',
|
|
222
|
+
records: [this.cloudfrontDistribution.domainName],
|
|
223
|
+
ttl: 60,
|
|
224
|
+
},
|
|
225
|
+
{ parent: this, provider: opts?.globalProvider }
|
|
226
|
+
);
|
|
30
227
|
}
|
|
31
228
|
}
|
|
@@ -7,6 +7,8 @@ export type ApplianceBaseAwsVpcArgs = {
|
|
|
7
7
|
|
|
8
8
|
export interface ApplianceBaseAwsVpcOpts extends pulumi.ComponentResourceOptions {
|
|
9
9
|
globalProvider?: pulumi.ProviderResource;
|
|
10
|
+
nativeProvider?: pulumi.ProviderResource;
|
|
11
|
+
nativeGlobalProvider?: pulumi.ProviderResource;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export class ApplianceBaseAwsVpc extends pulumi.ComponentResource {
|