@appliance.sh/infra 1.14.0 → 1.16.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 CHANGED
@@ -1,21 +1,33 @@
1
1
  {
2
2
  "name": "@appliance.sh/infra",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Deploy the Appliance Infrastructure",
5
5
  "repository": "https://github.com/appliance-sh/appliance.sh",
6
6
  "license": "MIT",
7
7
  "author": "Eliot Lim",
8
- "main": "src/index.ts",
8
+ "main": "dist/lib/index.js",
9
+ "types": "dist/lib/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/lib/index.d.ts",
13
+ "import": "./dist/lib/index.js",
14
+ "require": "./dist/lib/index.js"
15
+ }
16
+ },
9
17
  "scripts": {
10
18
  "test": "echo \"Error: no test specified\" && exit 1",
11
- "build": "echo \"No build required\"",
19
+ "build": "tsc",
12
20
  "deploy:entrypoint": "ts-node src/index.ts",
13
21
  "deploy": "pulumi up"
14
22
  },
15
23
  "dependencies": {
16
- "@pulumi/aws": "^7.15.0",
17
- "@pulumi/aws-native": "^1.46.0",
24
+ "@appliance.sh/sdk": "1.16.0",
25
+ "@pulumi/aws": "^7.16.0",
26
+ "@pulumi/aws-native": "^1.48.0",
18
27
  "@pulumi/awsx": "^3.1.0",
19
- "@pulumi/pulumi": "^3.213.0"
28
+ "@pulumi/pulumi": "^3.216.0"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.7.3"
20
32
  }
21
33
  }
@@ -0,0 +1,176 @@
1
+ import * as pulumi from '@pulumi/pulumi';
2
+ import * as aws from '@pulumi/aws';
3
+ import * as awsNative from '@pulumi/aws-native';
4
+ import { ApplianceBaseConfig } from '@appliance.sh/sdk';
5
+
6
+ export interface ApplianceStackArgs {
7
+ tags?: Record<string, string>;
8
+ config: ApplianceBaseConfig;
9
+ }
10
+
11
+ export interface ApplianceStackOpts extends pulumi.ComponentResourceOptions {
12
+ globalProvider: aws.Provider;
13
+ provider: aws.Provider;
14
+ nativeProvider: awsNative.Provider;
15
+ nativeGlobalProvider: awsNative.Provider;
16
+ }
17
+
18
+ export class ApplianceStack extends pulumi.ComponentResource {
19
+ lambdaRole: aws.iam.Role;
20
+ lambdaRolePolicy: aws.iam.Policy;
21
+ lambda: aws.lambda.Function;
22
+ lambdaUrl: aws.lambda.FunctionUrl;
23
+ dnsRecord: pulumi.Output<string>;
24
+
25
+ constructor(name: string, args: ApplianceStackArgs, opts: ApplianceStackOpts) {
26
+ super('appliance:aws:ApplianceStack', name, args, opts);
27
+
28
+ const defaultOpts = { parent: this, provider: opts.provider };
29
+ const defaultNativeOpts = { parent: this, provider: opts.nativeProvider };
30
+ const defaultTags = { stack: name, managed: 'appliance', ...args.tags };
31
+
32
+ this.lambdaRole = new aws.iam.Role(`${name}-role`, {
33
+ path: `/appliance/${name}/`,
34
+ assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: 'lambda.amazonaws.com' }),
35
+ tags: defaultTags,
36
+ });
37
+
38
+ this.lambdaRolePolicy = new aws.iam.Policy(`${name}-policy`, {
39
+ path: `/appliance/${name}/`,
40
+ policy: {
41
+ Version: '2012-10-17',
42
+ Statement: [{ Effect: 'Allow', Action: 'logs:CreateLogGroup', Resource: '*' }],
43
+ },
44
+ });
45
+
46
+ new aws.iam.RolePolicyAttachment(`${name}-role-policy-attachment`, {
47
+ role: this.lambdaRole.name,
48
+ policyArn: this.lambdaRolePolicy.arn,
49
+ });
50
+
51
+ this.lambda = new aws.lambda.CallbackFunction(
52
+ `${name}-handler`,
53
+ {
54
+ runtime: 'nodejs22.x',
55
+ callback: async () => {
56
+ return { statusCode: 200, body: JSON.stringify({ message: 'Hello world!' }) };
57
+ },
58
+ tags: defaultTags,
59
+ },
60
+ defaultOpts
61
+ );
62
+
63
+ // lambda url
64
+ this.lambdaUrl = new aws.lambda.FunctionUrl(
65
+ `${name}-url`,
66
+ {
67
+ functionName: this.lambda.name,
68
+ authorizationType: args.config.aws.cloudfrontDistributionId ? 'AWS_IAM' : 'NONE',
69
+ },
70
+ defaultOpts
71
+ );
72
+
73
+ this.dnsRecord = pulumi.interpolate`${name}.${args.config.domainName ?? ''}`;
74
+
75
+ if (args.config.aws.cloudfrontDistributionId) {
76
+ new aws.lambda.Permission(
77
+ `${name}-url-invoke-url-permission`,
78
+ {
79
+ function: this.lambda.name,
80
+ action: 'lambda:InvokeFunctionUrl',
81
+ principal: 'cloudfront.amazonaws.com',
82
+ functionUrlAuthType: 'AWS_IAM',
83
+ sourceArn: pulumi.interpolate`arn:aws:cloudfront::${
84
+ aws.getCallerIdentityOutput({}, { provider: opts.provider }).accountId
85
+ }:distribution/${args.config.aws.cloudfrontDistributionId}`,
86
+ statementId: 'FunctionURLAllowCloudFrontAccess',
87
+ },
88
+ defaultOpts
89
+ );
90
+
91
+ // Grant the edge router role permission to invoke the Lambda Function URL
92
+ // The edge router role is the execution role of the Lambda@Edge function that signs requests
93
+ if (args.config.aws.edgeRouterRoleArn) {
94
+ new aws.lambda.Permission(
95
+ `${name}-invoke-url-edge-router-permission`,
96
+ {
97
+ function: this.lambda.name,
98
+ action: 'lambda:InvokeFunctionUrl',
99
+ principal: args.config.aws.edgeRouterRoleArn,
100
+ functionUrlAuthType: 'AWS_IAM',
101
+ statementId: 'FunctionURLAllowEdgeRouterRoleAccess',
102
+ },
103
+ defaultOpts
104
+ );
105
+
106
+ new awsNative.lambda.Permission(
107
+ `${name}-invoke-edge-router-permission`,
108
+ {
109
+ action: 'lambda:InvokeFunction',
110
+ principal: args.config.aws.edgeRouterRoleArn,
111
+ functionName: this.lambda.name,
112
+ invokedViaFunctionUrl: true,
113
+ },
114
+ defaultNativeOpts
115
+ );
116
+ }
117
+ } else {
118
+ new aws.lambda.Permission(
119
+ `${name}-url-invoke-url-permission`,
120
+ {
121
+ function: this.lambda.name,
122
+ action: 'lambda:InvokeFunctionUrl',
123
+ principal: '*',
124
+ functionUrlAuthType: 'NONE',
125
+ statementId: 'FunctionURLAllowPublicAccess',
126
+ },
127
+ defaultOpts
128
+ );
129
+ }
130
+
131
+ if (args.config.aws.cloudfrontDistributionId && args.config.aws.cloudfrontDistributionDomainName) {
132
+ new awsNative.lambda.Permission(
133
+ `${name}-url-invoke-lambda-native-permission`,
134
+ {
135
+ action: 'lambda:InvokeFunction',
136
+ principal: 'cloudfront.amazonaws.com',
137
+ sourceArn: pulumi.interpolate`arn:aws:cloudfront::${
138
+ aws.getCallerIdentityOutput({}, { provider: opts.provider }).accountId
139
+ }:distribution/${args.config.aws.cloudfrontDistributionId}`,
140
+ functionName: this.lambda.name,
141
+ invokedViaFunctionUrl: true,
142
+ },
143
+ defaultNativeOpts
144
+ );
145
+
146
+ new aws.route53.Record(
147
+ `${name}-cname-record`,
148
+ {
149
+ zoneId: args.config.aws.zoneId,
150
+ name: pulumi.interpolate`${name}.${args.config.domainName ?? ''}`,
151
+ type: 'CNAME',
152
+ ttl: 60,
153
+ records: [args.config.aws.cloudfrontDistributionDomainName],
154
+ },
155
+ { parent: this, provider: opts.globalProvider }
156
+ );
157
+
158
+ new aws.route53.Record(
159
+ `${name}-txt-record`,
160
+ {
161
+ zoneId: args.config.aws.zoneId,
162
+ name: pulumi.interpolate`origin.${name}.${args.config.domainName ?? ''}`,
163
+ type: 'TXT',
164
+ ttl: 60,
165
+ records: [this.lambdaUrl.functionUrl],
166
+ },
167
+ { parent: this, provider: opts.globalProvider }
168
+ );
169
+ }
170
+
171
+ this.registerOutputs({
172
+ lambda: this.lambda,
173
+ lambdaUrl: this.lambdaUrl,
174
+ });
175
+ }
176
+ }
@@ -0,0 +1,10 @@
1
+ // AWS Infrastructure Components
2
+ export * from './aws/ApplianceStack';
3
+ export * from './aws/ApplianceBaseAwsPublic';
4
+ export * from './aws/ApplianceBaseAwsVpc';
5
+
6
+ // Controller
7
+ export * from './controller';
8
+
9
+ // Core infrastructure
10
+ export * from './appliance-infra';
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "nodenext",
5
+ "moduleResolution": "nodenext",
6
+ "resolvePackageJsonExports": true,
7
+ "esModuleInterop": true,
8
+ "isolatedModules": true,
9
+ "declaration": true,
10
+ "removeComments": true,
11
+ "emitDecoratorMetadata": true,
12
+ "experimentalDecorators": true,
13
+ "allowSyntheticDefaultImports": true,
14
+ "target": "ES2023",
15
+ "sourceMap": true,
16
+ "outDir": "./dist",
17
+ "baseUrl": "./",
18
+ "incremental": true,
19
+ "skipLibCheck": true,
20
+ "strictNullChecks": true,
21
+ "forceConsistentCasingInFileNames": true,
22
+ "noImplicitAny": false,
23
+ "strictBindCallApply": false,
24
+ "noFallthroughCasesInSwitch": false
25
+ }
26
+ }