Add an example for S3-triggered Lambdas
ADD
aws-ts-s3-lambda-copyzip/.gitignore
+/bin/
+/node_modules/

ADD
aws-ts-s3-lambda-copyzip/Pulumi.yaml
+name: slss-tps
+runtime: nodejs
+description: Copy and zip TPS reports, using AWS Lambda, from one S3 Bucket to another.

ADD
aws-ts-s3-lambda-copyzip/README.md
+[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new)
+
+# Serverless App to Copy and Zip S3 Objects Between Buckets
+
+This example sets up two AWS S3 Buckets and a single Lambda that listens to one and, upon each new
+object arriving in it, zips it up and copies it to the second bucket. Its architecture looks like this:
+
+![Architecture](./arch.png)
+
+This example is also featured in the blog post [Easy Serverless Apps and Infrastructure --
+Real Events, Real Code](https://blog.pulumi.com/easy-serverless-apps-and-infrastructure-real-events-real-code).
+
+## Deploying the App
+
+To deploy your new serverless application, follow the below steps.
+
+### Prerequisites
+
+1. [Install Pulumi](https://pulumi.io/install)
+2. [Configure AWS Credentials](https://pulumi.io/install/aws.html)
+
+### Steps
+
+After cloning this repo, from this working directory, run these commands:
+
+1. Create a new stack, which is an isolated environment for this example:
+
+ ```bash
+ $ pulumi stack init
+ ```
+
+ This will ask you to provide a name; `dev` is a fine name to begin with.
+
+2. Configure the AWS region for this program -- any valid AWS region will do:
+
+ ```bash
+ $ pulumi config set aws:region us-east-1
+ ```
+
+3. Deploy the application:
+
+ ```bash
+ $ pulumi up
+ ```
+
+4. After about 20 seconds, your buckets and lambda will have been deployed. Their names are printed:
+
+ ```bash
+ Outputs:
+ tpsReportsBucket: "tpsreports-21b7b7a"
+ tpsZipsBucket : "tpszips-c869600"
+ ```
+
+5. Now copy a file to the `tpsReportsBucket` using the AWS CLI:
+
+ ```bash
+ $ aws s3 cp ./myTpsReport001.txt s3://$(pulumi stack output tpsReportsBucket)
+ ```
+
+6. Tail the logs to see evidence the Lambda ran:
+
+ ```bash
+ $ pulumi logs -f
+ Collecting logs for stack dev since 2019-03-10T10:09:56.000-07:00...
+ 2019-03-10T11:10:48.617-07:00[zipTpsReports] Zipping
+ tpsreports-96458ef/tps001.txt into tpszips-edfde11/tps001.txt.zip
+ ```
+
+7. ^C out of `pulumi logs -f`, and then download your new zipfile!
+
+ ```bash
+ $ aws s3 cp s3://$(pulumi stack output tpsZipsBucket)/myTpsReport001.txt.zip .
+ ```
+
+7. Once you're done, destroy your stack and remove it -- eliminating all traces of running:
+
+ ```bash
+ # First, delete files so we can destroy the buckets (by default, bucket content isn't auto-deleted):
+ $ aws s3 rm s3://$(pulumi stack output tpsReportsBucket)/myTpsReport001.txt
+ $ aws s3 rm s3://$(pulumi stack output tpsZipsBucket)/myTpsReport001.txt.zip
+ $ pulumi destroy --yes
+ $ pulumi stack rm --yes
+ ```

ADD
aws-ts-s3-lambda-copyzip/arch.png
aws-ts-s3-lambda-copyzip/arch.png
Binary files /dev/null and b/aws-ts-s3-lambda-copyzip/arch.png differ

ADD
aws-ts-s3-lambda-copyzip/index.ts
+import * as pulumi from "@pulumi/pulumi";
+import * as aws from "@pulumi/aws";
+
+// Create a bucket each for TPS reports and their archived zips.
+const tpsReports = new aws.s3.Bucket("tpsReports");
+const tpsZips = new aws.s3.Bucket("tpsZips")
+
+// Anytime a new TPS Report is uploaded, archive it in a zipfile.
+tpsReports.onObjectCreated("zipTpsReports", (e) => {
+ const AdmZip = require("adm-zip");
+ const ops = [];
+ const s3 = new aws.sdk.S3();
+ for (const rec of e.Records || []) {
+ const zip = new AdmZip();
+ const [ buck, key ] = [ rec.s3.bucket.name, rec.s3.object.key ];
+ console.log(`Zipping ${buck}/${key} into ${tpsZips.bucket.get()}/${key}.zip`);
+ const zipOp = new Promise((resolve, reject) => {
+ s3.getObject(
+ { Bucket: buck, Key: key },
+ (err, data) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+ zip.addFile(key, data.Body);
+ // console.log(`Report: ${data.ContentLength}, Zip: ${zip.toBuffer().length}`);
+ s3.putObject(
+ {
+ Bucket: tpsZips.bucket.get(),
+ Key: `${key}.zip`,
+ Body: zip.toBuffer(),
+ },
+ (err) => {
+ if (err) reject(err);
+ else resolve();
+ },
+ );
+ });
+ });
+ ops.push(zipOp);
+ }
+ return Promise.all(ops).then(() => Promise.resolve());
+});
+
+// Finally, export the zipfile bucket name, for ease of access.
+export const tpsReportsBucket = tpsReports.bucket;
+export const tpsZipsBucket = tpsZips.bucket;

ADD
aws-ts-s3-lambda-copyzip/package.json
+{
+ "name": "slss-tps",
+ "devDependencies": {
+ "@types/node": "latest"
+ },
+ "dependencies": {
+ "@pulumi/aws": "^0.17.0",
+ "@pulumi/pulumi": "latest",
+ "adm-zip": "^0.4.13"
+ }
+}

ADD
aws-ts-s3-lambda-copyzip/tsconfig.json
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "target": "es6",
+ "lib": [
+ "es6"
+ ],
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "experimentalDecorators": true,
+ "pretty": true,
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitAny": true,
+ "noImplicitReturns": true,
+ "forceConsistentCasingInFileNames": true,
+ "strictNullChecks": true
+ },
+ "files": [
+ "index.ts"
+ ]
+}

Add an example for S3-triggered Lambdas (#255)