(
+
+
+
+
+
+ {assets}
+
+
+ {children}
+ {scripts}
+
+
+ )}
+ />
+));
diff --git a/examples/aws-solid-container-ws/src/global.d.ts b/examples/aws-solid-container-ws/src/global.d.ts
new file mode 100644
index 000000000..dc6f10c22
--- /dev/null
+++ b/examples/aws-solid-container-ws/src/global.d.ts
@@ -0,0 +1 @@
+///
diff --git a/examples/aws-solid-container-ws/src/routes/[...404].tsx b/examples/aws-solid-container-ws/src/routes/[...404].tsx
new file mode 100644
index 000000000..4ea71ec7f
--- /dev/null
+++ b/examples/aws-solid-container-ws/src/routes/[...404].tsx
@@ -0,0 +1,19 @@
+import { Title } from "@solidjs/meta";
+import { HttpStatusCode } from "@solidjs/start";
+
+export default function NotFound() {
+ return (
+
+ Not Found
+
+ Page Not Found
+
+ Visit{" "}
+
+ start.solidjs.com
+ {" "}
+ to learn how to build SolidStart apps.
+
+
+ );
+}
diff --git a/examples/aws-solid-container-ws/src/routes/about.tsx b/examples/aws-solid-container-ws/src/routes/about.tsx
new file mode 100644
index 000000000..8371d911c
--- /dev/null
+++ b/examples/aws-solid-container-ws/src/routes/about.tsx
@@ -0,0 +1,10 @@
+import { Title } from "@solidjs/meta";
+
+export default function Home() {
+ return (
+
+ About
+ About
+
+ );
+}
diff --git a/examples/aws-solid-container-ws/src/routes/index.tsx b/examples/aws-solid-container-ws/src/routes/index.tsx
new file mode 100644
index 000000000..5d557d819
--- /dev/null
+++ b/examples/aws-solid-container-ws/src/routes/index.tsx
@@ -0,0 +1,19 @@
+import { Title } from "@solidjs/meta";
+import Counter from "~/components/Counter";
+
+export default function Home() {
+ return (
+
+ Hello World
+ Hello world!
+
+
+ Visit{" "}
+
+ start.solidjs.com
+ {" "}
+ to learn how to build SolidStart apps.
+
+
+ );
+}
diff --git a/examples/aws-solid-container-ws/src/ws.ts b/examples/aws-solid-container-ws/src/ws.ts
new file mode 100644
index 000000000..7ee8d34f4
--- /dev/null
+++ b/examples/aws-solid-container-ws/src/ws.ts
@@ -0,0 +1,23 @@
+import { eventHandler } from "vinxi/http";
+export default eventHandler({
+ handler() { },
+ websocket: {
+ async open(peer) {
+ console.log("open", peer.id, peer.url);
+ },
+ async message(peer, msg) {
+ const message = msg.text();
+ console.log("msg", peer.id, peer.url, message);
+
+ setTimeout(() => {
+ peer.send("Message received from: #" + peer.id);
+ }, 3000);
+ },
+ async close(peer, _details) {
+ console.log("close", peer.id, peer.url);
+ },
+ async error(peer, error) {
+ console.log("error", peer.id, peer.url, error);
+ },
+ },
+});
diff --git a/examples/aws-solid-container-ws/sst-env.d.ts b/examples/aws-solid-container-ws/sst-env.d.ts
new file mode 100644
index 000000000..8beddcd4c
--- /dev/null
+++ b/examples/aws-solid-container-ws/sst-env.d.ts
@@ -0,0 +1,18 @@
+/* This file is auto-generated by SST. Do not edit. */
+/* tslint:disable */
+/* eslint-disable */
+import "sst"
+export {}
+declare module "sst" {
+ export interface Resource {
+ "MyService": {
+ "service": string
+ "type": "sst.aws.Service"
+ "url": string
+ }
+ "MyVpc": {
+ "bastion": string
+ "type": "sst.aws.Vpc"
+ }
+ }
+}
diff --git a/examples/aws-solid-container-ws/sst.config.ts b/examples/aws-solid-container-ws/sst.config.ts
new file mode 100644
index 000000000..d421bb7dd
--- /dev/null
+++ b/examples/aws-solid-container-ws/sst.config.ts
@@ -0,0 +1,50 @@
+///
+
+/**
+ * ## AWS SolidStart WebSocket endpoint
+ *
+ * Deploys a SolidStart app with a [WebSocket endpoint](https://docs.solidjs.com/solid-start/advanced/websocket)
+ * in a container to AWS.
+ *
+ * Uses the experimental WebSocket support in Nitro.
+ *
+ * ```ts title="app.config.ts" {4}
+ * export default defineConfig({
+ * server: {
+ * experimental: {
+ * websocket: true,
+ * },
+ * },
+ * }).addRouter({
+ * name: "ws",
+ * type: "http",
+ * handler: "./src/ws.ts",
+ * target: "server",
+ * base: "/ws",
+ * });
+ * ```
+ *
+ * Once deployed you can test the `/ws` endpoint and it'll send a message back after a 3s delay.
+ */
+export default $config({
+ app(input) {
+ return {
+ name: "aws-solid-container-ws",
+ removal: input?.stage === "production" ? "retain" : "remove",
+ home: "aws",
+ };
+ },
+ async run() {
+ const vpc = new sst.aws.Vpc("MyVpc", { bastion: true });
+ const cluster = new sst.aws.Cluster("MyCluster", { vpc });
+
+ cluster.addService("MyService", {
+ public: {
+ ports: [{ listen: "80/http", forward: "3000/http" }],
+ },
+ dev: {
+ command: "npm run dev",
+ },
+ });
+ },
+});
diff --git a/examples/aws-solid-container-ws/tsconfig.json b/examples/aws-solid-container-ws/tsconfig.json
new file mode 100644
index 000000000..7d5871a07
--- /dev/null
+++ b/examples/aws-solid-container-ws/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+ "allowJs": true,
+ "strict": true,
+ "noEmit": true,
+ "types": ["vinxi/types/client"],
+ "isolatedModules": true,
+ "paths": {
+ "~/*": ["./src/*"]
+ }
+ }
+}
diff --git a/www/src/content/docs/docs/examples.mdx b/www/src/content/docs/docs/examples.mdx
index 602f26157..439734bad 100644
--- a/www/src/content/docs/docs/examples.mdx
+++ b/www/src/content/docs/docs/examples.mdx
@@ -127,16 +127,15 @@ Create an S3 bucket and transform its bucket policy.
const bucket = new sst.aws.Bucket("MyBucket", {
transform: {
policy: (args) => {
- // use $jsonParse and $jsonStringify helper functions to manipulate JSON strings
+ // use sst.aws.iamEdit helper function to manipulate IAM policy
// containing Output values from components
- args.policy = $jsonParse(args.policy).apply((policy) => {
+ args.policy = sst.aws.iamEdit(args.policy, (policy) => {
policy.Statement.push({
Effect: "Allow",
Principal: { Service: "ses.amazonaws.com" },
Action: "s3:PutObject",
Resource: $interpolate`arn:aws:s3:::${args.bucket}/*`,
});
- return $jsonStringify(policy);
});
},
},
@@ -403,6 +402,75 @@ return {
View the [full example](https://github.com/sst/ion/tree/dev/examples/aws-dynamo).
+---
+## EC2 with Pulumi
+
+Use raw Pulumi resources to create an EC2 instance.
+```ts title="sst.config.ts"
+
+
+
+# EC2 with Pulumi
+
+se raw Pulumi resources to create an EC2 instance.
+
+rt default $config({
+(input) {
+turn {
+ame: "aws-ec2-pulumi",
+ome: "aws",
+emoval: input?.stage === "production" ? "retain" : "remove",
+
+
+nc run() {
+ Notice you don't need to import pulumi, it is already part of sst.
+nst securityGroup = new aws.ec2.SecurityGroup("web-secgrp", {
+ngress: [
+{
+ protocol: "tcp",
+ fromPort: 80,
+ toPort: 80,
+ cidrBlocks: ["0.0.0.0/0"],
+},
+,
+;
+
+ Find the latest Ubuntu AMI
+nst ami = aws.ec2.getAmi({
+ilters: [
+{
+ name: "name",
+ values: ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"],
+},
+,
+ostRecent: true,
+wners: ["099720109477"], // Canonical
+;
+
+ User data to set up a simple web server
+nst userData = `#!/bin/bash
+ho "Hello, World!" > index.html
+hup python3 -m http.server 80 &`;
+
+ Create an EC2 instance
+nst server = new aws.ec2.Instance("web-server", {
+nstanceType: "t2.micro",
+mi: ami.then((ami) => ami.id),
+serData: userData,
+pcSecurityGroupIds: [securityGroup.id],
+ssociatePublicIpAddress: true,
+;
+
+turn {
+pp: server.publicIp,
+
+
+
+```
+
+View the [full example](https://github.com/sst/ion/tree/dev/examples/aws-ec2-pulumi).
+
+
---
## AWS Express file upload
@@ -813,7 +881,7 @@ This needs _sudo_ to create the network interface on your machine. You'll only n
this once.
Now you can run `sst dev`, your function can access resources in the VPC. For example, here
-we're connecting to a Redis cluster.
+we are connecting to a Redis cluster.
```ts title="index.ts"
const redis = new Cluster(
@@ -1380,6 +1448,48 @@ return {
View the [full example](https://github.com/sst/ion/tree/dev/examples/aws-sharp).
+---
+## AWS SolidStart WebSocket endpoint
+
+Deploys a SolidStart app with a [WebSocket endpoint](https://docs.solidjs.com/solid-start/advanced/websocket)
+in a container to AWS.
+
+Uses the experimental WebSocket support in Nitro.
+
+```ts title="app.config.ts" {4}
+export default defineConfig({
+ server: {
+ experimental: {
+ websocket: true,
+ },
+ },
+}).addRouter({
+ name: "ws",
+ type: "http",
+ handler: "./src/ws.ts",
+ target: "server",
+ base: "/ws",
+});
+```
+
+Once deployed you can test the `/ws` endpoint and it'll send a message back after a 3s delay.
+```ts title="sst.config.ts"
+const vpc = new sst.aws.Vpc("MyVpc", { bastion: true });
+const cluster = new sst.aws.Cluster("MyCluster", { vpc });
+
+cluster.addService("MyService", {
+ public: {
+ ports: [{ listen: "80/http", forward: "3000/http" }],
+ },
+ dev: {
+ command: "npm run dev",
+ },
+});
+```
+
+View the [full example](https://github.com/sst/ion/tree/dev/examples/aws-solid-container-ws).
+
+
---
## AWS static site basic auth
diff --git a/www/src/content/docs/docs/start/aws/solid.mdx b/www/src/content/docs/docs/start/aws/solid.mdx
index 7e6b562ed..2d6710ab5 100644
--- a/www/src/content/docs/docs/start/aws/solid.mdx
+++ b/www/src/content/docs/docs/start/aws/solid.mdx
@@ -12,6 +12,14 @@ We'll use both to build a couple of simple apps below.
---
+#### Examples
+
+We also have a few other SolidStart examples that you can refer to.
+
+- [Adding a WebSocket endpoint to SolidStart](/docs/examples/#aws-solidstart-websocket-endpoint)
+
+---
+
## Serverless
We are going to create a SolidStart app, add an S3 Bucket for file uploads, and deploy it using the `SolidStart` component.
@@ -250,7 +258,7 @@ async run() {
cluster.addService("MyService", {
public: {
- ports: [{ listen: "80/http", forward: "4321/http" }],
+ ports: [{ listen: "80/http", forward: "3000/http" }],
},
dev: {
command: "npm run dev",