@appliance.sh/api-server 1.13.0 → 1.14.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/package.json +1 -1
- package/src/pulumi/ApplianceStack.ts +92 -14
- package/src/pulumi/pulumi.service.ts +19 -3
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
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
|
+
import { ApplianceBaseConfig } from '@appliance.sh/sdk';
|
|
3
5
|
|
|
4
6
|
export interface ApplianceStackArgs {
|
|
5
7
|
tags?: Record<string, string>;
|
|
8
|
+
config: ApplianceBaseConfig;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
export interface ApplianceStackOpts extends pulumi.ComponentResourceOptions {
|
|
9
12
|
globalProvider: aws.Provider;
|
|
10
13
|
provider: aws.Provider;
|
|
14
|
+
nativeProvider: awsNative.Provider;
|
|
15
|
+
nativeGlobalProvider: awsNative.Provider;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
export class ApplianceStack extends pulumi.ComponentResource {
|
|
@@ -15,11 +20,13 @@ export class ApplianceStack extends pulumi.ComponentResource {
|
|
|
15
20
|
lambdaRolePolicy: aws.iam.Policy;
|
|
16
21
|
lambda: aws.lambda.Function;
|
|
17
22
|
lambdaUrl: aws.lambda.FunctionUrl;
|
|
23
|
+
dnsRecord: pulumi.Output<string>;
|
|
18
24
|
|
|
19
25
|
constructor(name: string, args: ApplianceStackArgs, opts: ApplianceStackOpts) {
|
|
20
26
|
super('appliance:aws:ApplianceStack', name, args, opts);
|
|
21
27
|
|
|
22
28
|
const defaultOpts = { parent: this, provider: opts.provider };
|
|
29
|
+
const defaultNativeOpts = { parent: this, provider: opts.nativeProvider };
|
|
23
30
|
const defaultTags = { stack: name, managed: 'appliance', ...args.tags };
|
|
24
31
|
|
|
25
32
|
this.lambdaRole = new aws.iam.Role(`${name}-role`, {
|
|
@@ -58,25 +65,96 @@ export class ApplianceStack extends pulumi.ComponentResource {
|
|
|
58
65
|
`${name}-url`,
|
|
59
66
|
{
|
|
60
67
|
functionName: this.lambda.name,
|
|
61
|
-
authorizationType: 'NONE',
|
|
68
|
+
authorizationType: args.config.aws.cloudfrontDistributionId ? 'AWS_IAM' : 'NONE',
|
|
62
69
|
},
|
|
63
70
|
defaultOpts
|
|
64
71
|
);
|
|
65
72
|
|
|
66
|
-
|
|
67
|
-
function: this.lambda.name,
|
|
68
|
-
action: 'lambda:InvokeFunctionUrl',
|
|
69
|
-
principal: '*',
|
|
70
|
-
functionUrlAuthType: 'NONE',
|
|
71
|
-
statementId: 'FunctionURLAllowPublicAccess',
|
|
72
|
-
});
|
|
73
|
+
this.dnsRecord = pulumi.interpolate`${name}.${args.config.domainName ?? ''}`;
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
if (args.config.aws.cloudfrontDistributionId) {
|
|
76
|
+
new aws.lambda.Permission(`${name}-url-invoke-url-permission`, {
|
|
77
|
+
function: this.lambda.name,
|
|
78
|
+
action: 'lambda:InvokeFunctionUrl',
|
|
79
|
+
principal: 'cloudfront.amazonaws.com',
|
|
80
|
+
functionUrlAuthType: 'AWS_IAM',
|
|
81
|
+
sourceArn: pulumi.interpolate`arn:aws:cloudfront::${
|
|
82
|
+
aws.getCallerIdentityOutput({}, { provider: opts.provider }).accountId
|
|
83
|
+
}:distribution/${args.config.aws.cloudfrontDistributionId}`,
|
|
84
|
+
statementId: 'FunctionURLAllowCloudFrontAccess',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Grant the edge router role permission to invoke the Lambda Function URL
|
|
88
|
+
// The edge router role is the execution role of the Lambda@Edge function that signs requests
|
|
89
|
+
if (args.config.aws.edgeRouterRoleArn) {
|
|
90
|
+
new aws.lambda.Permission(`${name}-invoke-url-edge-router-permission`, {
|
|
91
|
+
function: this.lambda.name,
|
|
92
|
+
action: 'lambda:InvokeFunctionUrl',
|
|
93
|
+
principal: args.config.aws.edgeRouterRoleArn,
|
|
94
|
+
functionUrlAuthType: 'AWS_IAM',
|
|
95
|
+
statementId: 'FunctionURLAllowEdgeRouterRoleAccess',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
new awsNative.lambda.Permission(
|
|
99
|
+
`${name}-invoke-edge-router-permission`,
|
|
100
|
+
{
|
|
101
|
+
action: 'lambda:InvokeFunction',
|
|
102
|
+
principal: args.config.aws.edgeRouterRoleArn,
|
|
103
|
+
functionName: this.lambda.name,
|
|
104
|
+
invokedViaFunctionUrl: true,
|
|
105
|
+
},
|
|
106
|
+
defaultNativeOpts
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
new aws.lambda.Permission(`${name}-url-invoke-url-permission`, {
|
|
111
|
+
function: this.lambda.name,
|
|
112
|
+
action: 'lambda:InvokeFunctionUrl',
|
|
113
|
+
principal: '*',
|
|
114
|
+
functionUrlAuthType: 'NONE',
|
|
115
|
+
statementId: 'FunctionURLAllowPublicAccess',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (args.config.aws.cloudfrontDistributionId && args.config.aws.cloudfrontDistributionDomainName) {
|
|
120
|
+
new awsNative.lambda.Permission(
|
|
121
|
+
`${name}-url-invoke-lambda-native-permission`,
|
|
122
|
+
{
|
|
123
|
+
action: 'lambda:InvokeFunction',
|
|
124
|
+
principal: 'cloudfront.amazonaws.com',
|
|
125
|
+
sourceArn: pulumi.interpolate`arn:aws:cloudfront::${
|
|
126
|
+
aws.getCallerIdentityOutput({}, { provider: opts.provider }).accountId
|
|
127
|
+
}:distribution/${args.config.aws.cloudfrontDistributionId}`,
|
|
128
|
+
functionName: this.lambda.name,
|
|
129
|
+
invokedViaFunctionUrl: true,
|
|
130
|
+
},
|
|
131
|
+
defaultNativeOpts
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
new aws.route53.Record(
|
|
135
|
+
`${name}-cname-record`,
|
|
136
|
+
{
|
|
137
|
+
zoneId: args.config.aws.zoneId,
|
|
138
|
+
name: pulumi.interpolate`${name}.${args.config.domainName ?? ''}`,
|
|
139
|
+
type: 'CNAME',
|
|
140
|
+
ttl: 60,
|
|
141
|
+
records: [args.config.aws.cloudfrontDistributionDomainName],
|
|
142
|
+
},
|
|
143
|
+
{ parent: this, provider: opts.globalProvider }
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
new aws.route53.Record(
|
|
147
|
+
`${name}-txt-record`,
|
|
148
|
+
{
|
|
149
|
+
zoneId: args.config.aws.zoneId,
|
|
150
|
+
name: pulumi.interpolate`origin.${name}.${args.config.domainName ?? ''}`,
|
|
151
|
+
type: 'TXT',
|
|
152
|
+
ttl: 60,
|
|
153
|
+
records: [this.lambdaUrl.functionUrl],
|
|
154
|
+
},
|
|
155
|
+
{ parent: this, provider: opts.globalProvider }
|
|
156
|
+
);
|
|
157
|
+
}
|
|
80
158
|
|
|
81
159
|
this.registerOutputs({
|
|
82
160
|
lambda: this.lambda,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
2
|
import * as auto from '@pulumi/pulumi/automation';
|
|
3
3
|
import * as aws from '@pulumi/aws';
|
|
4
|
+
import * as awsNative from '@pulumi/aws-native';
|
|
4
5
|
import { ApplianceStack } from './ApplianceStack';
|
|
5
6
|
import { applianceBaseConfig } from '@appliance.sh/sdk';
|
|
6
7
|
|
|
@@ -17,31 +18,46 @@ export interface PulumiResult {
|
|
|
17
18
|
@Injectable()
|
|
18
19
|
export class PulumiService {
|
|
19
20
|
private readonly logger = new Logger(PulumiService.name);
|
|
20
|
-
private readonly region = process.env.AWS_REGION || 'us-east-1';
|
|
21
21
|
private readonly projectName = 'appliance-api-managed-proj';
|
|
22
22
|
|
|
23
23
|
private readonly baseConfig = process.env.APPLIANCE_BASE_CONFIG
|
|
24
24
|
? applianceBaseConfig.parse(JSON.parse(process.env.APPLIANCE_BASE_CONFIG))
|
|
25
25
|
: undefined;
|
|
26
|
+
private readonly region = this.baseConfig?.aws.region || 'us-east-1';
|
|
26
27
|
|
|
27
28
|
private inlineProgram() {
|
|
28
29
|
return async () => {
|
|
29
30
|
const name = 'appliance';
|
|
31
|
+
|
|
32
|
+
if (!this.baseConfig) {
|
|
33
|
+
throw new Error('Missing base config');
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
const regionalProvider = new aws.Provider(`${name}-regional`, {
|
|
31
|
-
region: this.baseConfig?.region ?? 'ap-southeast-1',
|
|
37
|
+
region: (this.baseConfig?.aws.region as aws.Region) ?? 'ap-southeast-1',
|
|
32
38
|
});
|
|
33
39
|
const globalProvider = new aws.Provider(`${name}-global`, {
|
|
34
40
|
region: 'us-east-1',
|
|
35
41
|
});
|
|
42
|
+
const nativeRegionalProvider = new awsNative.Provider(`${name}-native-regional`, {
|
|
43
|
+
region: (this.baseConfig?.aws.region as awsNative.Region) ?? 'ap-southeast-1',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const nativeGlobalProvider = new awsNative.Provider(`${name}-native-global`, {
|
|
47
|
+
region: 'us-east-1',
|
|
48
|
+
});
|
|
36
49
|
|
|
37
50
|
const applianceStack = new ApplianceStack(
|
|
38
51
|
`${name}-stack`,
|
|
39
52
|
{
|
|
40
53
|
tags: { project: name },
|
|
54
|
+
config: this.baseConfig,
|
|
41
55
|
},
|
|
42
56
|
{
|
|
43
57
|
globalProvider,
|
|
44
58
|
provider: regionalProvider,
|
|
59
|
+
nativeProvider: nativeRegionalProvider,
|
|
60
|
+
nativeGlobalProvider: nativeGlobalProvider,
|
|
45
61
|
}
|
|
46
62
|
);
|
|
47
63
|
|
|
@@ -67,7 +83,7 @@ export class PulumiService {
|
|
|
67
83
|
{ projectName: this.projectName, stackName, program },
|
|
68
84
|
{ envVars }
|
|
69
85
|
);
|
|
70
|
-
await stack.setConfig('aws:region', { value: this.region });
|
|
86
|
+
await stack.setConfig('aws:region', { value: this.baseConfig.aws.region });
|
|
71
87
|
return stack;
|
|
72
88
|
}
|
|
73
89
|
|