@cloudnux/cli 0.20.0 → 0.21.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/.deploy/aws/sns/main.tf +33 -0
- package/.deploy/aws/sns/variables.tf +18 -0
- package/dist/cli.mjs +1 -0
- package/dist/index.mjs +1 -0
- package/dist/templates/cloud/entrypoint-triggers.tf.ejs +19 -0
- package/dist/templates/local/dev-server.ts.ejs +4 -2
- package/dist/templates/local/module.ts.ejs +11 -2
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# SNS Trigger Module - main.tf
|
|
2
|
+
|
|
3
|
+
data "aws_sns_topic" "this" {
|
|
4
|
+
for_each = var.event_sources
|
|
5
|
+
name = each.value.topic_name
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
resource "aws_sns_topic_subscription" "this" {
|
|
9
|
+
for_each = var.event_sources
|
|
10
|
+
|
|
11
|
+
topic_arn = data.aws_sns_topic.this[each.key].arn
|
|
12
|
+
protocol = "lambda"
|
|
13
|
+
endpoint = var.lambda_arn
|
|
14
|
+
|
|
15
|
+
filter_policy = try(each.value.filter_policy, null)
|
|
16
|
+
filter_policy_scope = try(each.value.filter_policy, null) != null ? try(each.value.filter_policy_scope, "MessageAttributes") : null
|
|
17
|
+
|
|
18
|
+
lifecycle {
|
|
19
|
+
create_before_destroy = true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# SNS (unlike SQS event source mappings) requires an explicit resource-based
|
|
24
|
+
# permission for the topic to invoke the Lambda function.
|
|
25
|
+
resource "aws_lambda_permission" "allow_sns" {
|
|
26
|
+
for_each = var.event_sources
|
|
27
|
+
|
|
28
|
+
statement_id = "AllowExecutionFromSNS-${each.key}"
|
|
29
|
+
action = "lambda:InvokeFunction"
|
|
30
|
+
function_name = var.lambda_name
|
|
31
|
+
principal = "sns.amazonaws.com"
|
|
32
|
+
source_arn = data.aws_sns_topic.this[each.key].arn
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
variable "event_sources" {
|
|
2
|
+
description = "Map of SNS event source configurations"
|
|
3
|
+
type = map(object({
|
|
4
|
+
topic_name = string
|
|
5
|
+
filter_policy = optional(string)
|
|
6
|
+
filter_policy_scope = optional(string, "MessageAttributes")
|
|
7
|
+
}))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
variable "lambda_name" {
|
|
11
|
+
description = "Name of the Lambda function"
|
|
12
|
+
type = string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
variable "lambda_arn" {
|
|
16
|
+
description = "ARN of the Lambda function"
|
|
17
|
+
type = string
|
|
18
|
+
}
|
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -98,6 +98,25 @@ module "sqs_trigger_for_<%= namespace %>_<%= module %>" {
|
|
|
98
98
|
}
|
|
99
99
|
<%_ } _%>
|
|
100
100
|
|
|
101
|
+
<%_
|
|
102
|
+
// ── Event (SNS) triggers ─────────────────────────────────────────────────────
|
|
103
|
+
const snsEntries = Object.entries(entries).filter(([, e]) => e.trigger.type.toLowerCase() === "event" && e.trigger.options.sourceType?.toLowerCase() === "sns");
|
|
104
|
+
_%>
|
|
105
|
+
<%_ if (snsEntries.length > 0) { _%>
|
|
106
|
+
module "sns_trigger_for_<%= namespace %>_<%= module %>" {
|
|
107
|
+
source = "<%= tfModules.sns %>"
|
|
108
|
+
lambda_name = "<%= namespace %>_<%= module %>"
|
|
109
|
+
lambda_arn = data.aws_lambda_function.this.arn
|
|
110
|
+
event_sources = {
|
|
111
|
+
<%_ for (const [key, entry] of snsEntries) { _%>
|
|
112
|
+
"<%= key %>" = {
|
|
113
|
+
topic_name = "<%= entry.trigger.options.source %>"
|
|
114
|
+
}
|
|
115
|
+
<%_ } _%>
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
<%_ } _%>
|
|
119
|
+
|
|
101
120
|
<%_
|
|
102
121
|
// ── WebSocket triggers ───────────────────────────────────────────────────────
|
|
103
122
|
const wsEntries = Object.entries(entries).filter(([, e]) => e.trigger.type.toLowerCase() === "websocket");
|
|
@@ -12,6 +12,8 @@ import <%=svc.varName%> from "<%-svc.path%>";
|
|
|
12
12
|
|
|
13
13
|
// __dirname is injected by the esbuild banner and resolves to the workingDir/env folder
|
|
14
14
|
process.env.DEV_CLOUD_LOCATION_PATH ??= path.join(__dirname, '.local-location');
|
|
15
|
+
process.env.DEV_CLOUD_STORAGE_BUCKET ??= path.join(__dirname, '.local-storage');
|
|
16
|
+
process.env.DEV_CLOUD_EMAIL_DIR ??= path.join(__dirname, '.local-email');
|
|
15
17
|
|
|
16
18
|
useCloudProvider(localCloudProvider<% if (serviceOverrides.length) { %>, { serviceFactories: { <%- serviceOverrides.map(svc => `"${svc.kind}": ${svc.varName}`).join(', ') %> } }<% } %>);
|
|
17
19
|
|
|
@@ -21,8 +23,8 @@ import <%=module%>Entries from "./<%=module%>"
|
|
|
21
23
|
|
|
22
24
|
const router = createRouter();
|
|
23
25
|
|
|
24
|
-
router.register(queuesPlugin, { prefix: "queues", config: { persistence: { directory: path.join(__dirname, 'queue-data') } } });
|
|
25
|
-
router.register(schedulerPlugin, { prefix: "schedules", config: { persistence: { directory: path.join(__dirname, 'scheduler-data') } } });
|
|
26
|
+
router.register(queuesPlugin, { prefix: "queues", config: { persistence: { directory: path.join(__dirname, '.queue-data') } } });
|
|
27
|
+
router.register(schedulerPlugin, { prefix: "schedules", config: { persistence: { directory: path.join(__dirname, '.scheduler-data') } } });
|
|
26
28
|
router.register(devConsolePlugin, { prefix: 'console' });
|
|
27
29
|
router.register(websocketsPlugin, { prefix: "websockets" });
|
|
28
30
|
router.register(invokesPlugin);
|
|
@@ -34,11 +34,20 @@ async function entries(app: RouterInstance) {
|
|
|
34
34
|
return scheduleHandler(src["<%= entry.handler %>"], job,execution)
|
|
35
35
|
}});
|
|
36
36
|
<%_ } _%>
|
|
37
|
-
<%_ if(entry.trigger.type === "event") {
|
|
38
|
-
|
|
37
|
+
<%_ if(entry.trigger.type === "event") {
|
|
38
|
+
// SNS-sourced entries get their own subscriber queue - a topic can have
|
|
39
|
+
// multiple independent subscribers, unlike a plain SQS-sourced queue
|
|
40
|
+
// which is addressed directly and only ever has the one consumer.
|
|
41
|
+
const isTopic = entry.trigger.options.sourceType === "sns";
|
|
42
|
+
const queueName = isTopic ? `${entry.trigger.options.source}--${module}--${name}` : entry.trigger.options.source;
|
|
43
|
+
_%>
|
|
44
|
+
app.queues.addQueue("<%=queueName%>",
|
|
39
45
|
(msg) => eventBrokerHandler(src["<%= entry.handler %>"], msg),
|
|
40
46
|
"<%=module%>"
|
|
41
47
|
);
|
|
48
|
+
<%_ if(isTopic) { _%>
|
|
49
|
+
app.queues.subscribeTopic("<%=entry.trigger.options.source%>", "<%=queueName%>");
|
|
50
|
+
<%_ } _%>
|
|
42
51
|
<%_ } _%>
|
|
43
52
|
<%_ if(entry.trigger.type === "invoke") { _%>
|
|
44
53
|
app.invokes.register("<%=module%>","<%= entry.trigger.options.name %>",
|