Skip to content

Commit

Permalink
Merge pull request #5 from pulumi/donna-wip
Browse files Browse the repository at this point in the history
Minor improvements to voting-app and webserver
  • Loading branch information
lindydonna committed Dec 18, 2017
2 parents 82b8f12 + 77089bc commit a1a34e9
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 30 deletions.
59 changes: 59 additions & 0 deletions .vscode/tasks.json
@@ -0,0 +1,59 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Voting app",
"type": "typescript",
"tsconfig": "voting-app/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "url shortener",
"type": "typescript",
"tsconfig": "url-shortener/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "webserver",
"type": "typescript",
"tsconfig": "webserver/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "webserver-component",
"type": "typescript",
"tsconfig": "webserver-component/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
23 changes: 14 additions & 9 deletions voting-app/index.ts
Expand Up @@ -4,36 +4,41 @@ import * as cloud from "@pulumi/cloud";

// To simplify this example, we have defined the password directly in code
// In a real app, would add the secret via `pulumi config secret <key> <value>` and
// access via config APIs
// access via pulumi.Config APIs
let redisPassword = "SECRETPASSWORD";

let redisPort = 6379;

// The data layer for the application
// Use the 'image' property to point to a pre-built Docker image.
let redisCache = new cloud.Service("voting-app-cache", {
containers: {
redis: {
image: "redis:alpine",
memory: 128,
ports: [{ port: redisPort }],
ports: [{ port: 6379 }],
command: ["redis-server", "--requirepass", redisPassword],
},
},
});

// A custom container for the frontend, which is a Python Flask app
// Use the 'build' property to specify a folder that contains a Dockerfile.
// Pulumi builds the container for you and pushes to an ECR registry
let frontend = new cloud.Service("voting-app-frontend", {
containers: {
votingAppFrontend: {
build: "./frontend",
build: "./frontend", // path to the folder containing the Dockerfile
memory: 128,
ports: [{ port: 80 }],
environment: {
// pass in the created container info in environment variables
"REDIS": redisCache.getEndpoint("redis", redisPort).then(e => e.hostname),
"REDIS_PORT": redisCache.getEndpoint("redis", redisPort).then(e => e.port).then(port => port.toString()),
// pass the Redis container info in environment variables
// (the use of promises will be improved in the future)
"REDIS": redisCache.getEndpoint().then(e => e.hostname),
"REDIS_PORT": redisCache.getEndpoint().then(e => e.port.toString()),
"REDIS_PWD": redisPassword
}
},
},
});

frontend.getEndpoint().then(e => console.log(`http://${e.hostname}:${e.port}`));
// Export a variable that will be displayed during 'pulumi update'
export let frontendURL = frontend.getEndpoint().then(e => `http://${e.hostname}:${e.port}`);
4 changes: 4 additions & 0 deletions webserver-component/.gitignore
@@ -0,0 +1,4 @@
/.pulumi/
/bin/
/node_modules/
/yarn.lock
7 changes: 7 additions & 0 deletions webserver-component/Pulumi.yaml
@@ -0,0 +1,7 @@
name: webserver
runtime: nodejs
description: Basic example of an AWS web server accessible over HTTP.
stacks:
testing:
config:
aws:config:region: us-west-2
5 changes: 5 additions & 0 deletions webserver-component/index.ts
@@ -0,0 +1,5 @@
import * as aws from "@pulumi/aws";
import * as webserver from "./webserver"; // use the new custom component

let webInstance = webserver.createInstance("web-server-www", "t2.micro");
let appInstance = webserver.createInstance("web-server-app", "t2.nano");
19 changes: 19 additions & 0 deletions webserver-component/package.json
@@ -0,0 +1,19 @@
{
"name": "webserver",
"version": "0.1",
"main": "bin/index.js",
"typings": "bin/index.d.ts",
"scripts": {
"build": "tsc"
},
"devDependencies": {
"typescript": "^2.5.3"
},
"peerDependencies": {
"@pulumi/aws": "*",
"pulumi": "*"
},
"dependencies": {
"@types/node": "^8.0.26"
}
}
24 changes: 24 additions & 0 deletions webserver-component/tsconfig.json
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"outDir": "bin",
"target": "es6",
"lib": [
"es6"
],
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"stripInternal": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true
},
"files": [
"index.ts"
]
}
31 changes: 31 additions & 0 deletions webserver-component/webserver.ts
@@ -0,0 +1,31 @@
import * as aws from "@pulumi/aws";

// create a new security group for port 80
let group = new aws.ec2.SecurityGroup("web-secgrp", {
description: "Enable HTTP access",
ingress: [
{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
],
});

// (optional) create a simple web server using the startup script for the instance
// use the AWS metadata service to get the availability zone for the instance
let userData =
`#!/bin/bash
echo "Hello, World!\nInstance metadata:" > index.html
curl http://169.254.169.254/latest/meta-data/placement/availability-zone >> index.html
nohup python -m SimpleHTTPServer 80 &`;

export function createInstance(name: string, size: aws.ec2.InstanceType): aws.ec2.Instance {
let result = new aws.ec2.Instance(name, {
tags: { "Name": name }, // use the `name` parameter
instanceType: size, // use function argument for size
securityGroups: [ group.name ], // reference the group object above
ami: aws.ec2.getLinuxAMI(size), // call built-in function (can also be custom)
userData: userData // set up a simple web server
});

result.publicDns.then(url => console.log(`Server URL: http://${url}`));

return result;
}
4 changes: 4 additions & 0 deletions webserver-zones/.gitignore
@@ -0,0 +1,4 @@
/.pulumi/
/bin/
/node_modules/
/yarn.lock
3 changes: 3 additions & 0 deletions webserver-zones/Pulumi.yaml
@@ -0,0 +1,3 @@
name: webserver
runtime: nodejs
description: Basic example of an AWS web server accessible over HTTP.
3 changes: 3 additions & 0 deletions webserver-zones/README.md
@@ -0,0 +1,3 @@
# Pulumi web server

Starting point for building the Pulumi web server sample.
11 changes: 11 additions & 0 deletions webserver-zones/index.ts
@@ -0,0 +1,11 @@
import * as aws from "@pulumi/aws";
import * as webserver from "./webserver"; // use the new custom component

// the async block is currently required, due to the use of `await`
// this will be improved in the future
(async () => {
let zones: string[] = (await aws.getAvailabilityZones()).names;
for (let i = 0; i < zones.length; i++) {
let server = webserver.createInstance(`web-server-www-${i}`, "t2.micro", zones[i]);
}
})();
19 changes: 19 additions & 0 deletions webserver-zones/package.json
@@ -0,0 +1,19 @@
{
"name": "webserver",
"version": "0.1",
"main": "bin/index.js",
"typings": "bin/index.d.ts",
"scripts": {
"build": "tsc"
},
"devDependencies": {
"typescript": "^2.5.3"
},
"peerDependencies": {
"@pulumi/aws": "*",
"pulumi": "*"
},
"dependencies": {
"@types/node": "^8.0.26"
}
}
24 changes: 24 additions & 0 deletions webserver-zones/tsconfig.json
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"outDir": "bin",
"target": "es6",
"lib": [
"es6"
],
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"stripInternal": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true
},
"files": [
"index.ts"
]
}
17 changes: 4 additions & 13 deletions webserver/webserver.ts → webserver-zones/webserver.ts
@@ -1,7 +1,5 @@
import * as aws from "@pulumi/aws";

export let size: aws.ec2.InstanceType = "t2.micro"; // the type InstanceType contains friendly names for AWS instance sizes

// create a new security group for port 80
let group = new aws.ec2.SecurityGroup("web-secgrp", {
description: "Enable HTTP access",
Expand All @@ -10,15 +8,8 @@ let group = new aws.ec2.SecurityGroup("web-secgrp", {
],
});

// a function to find the Amazon Linux AMI for the current region
async function getLinuxAmi() {
let result = await aws.getAmi({
owners: ["amazon"],
filter: [{ name: "name", values: ["amzn-ami-2017.03.g-amazon-ecs-optimized"] }]
});
return result.imageId;
}

// (optional) create a simple web server using the startup script for the instance
// use the AWS metadata service to get the availability zone for the instance
let userData =
`#!/bin/bash
echo "Hello, World!\nInstance metadata:" > index.html
Expand All @@ -28,10 +19,10 @@ let userData =
export function createInstance(name: string, size: aws.ec2.InstanceType, zone: string): aws.ec2.Instance {
let result = new aws.ec2.Instance(name, {
availabilityZone: zone,
tags: { "Name": name },
instanceType: size, // use function argument for size
securityGroups: [ group.name ], // reference the group object above
ami: getLinuxAmi(), // call custom function
tags: { "Name": name },
ami: aws.ec2.getLinuxAMI(size), // call built-in function (can also be custom)
userData: userData // set up a simple web server
});

Expand Down
37 changes: 29 additions & 8 deletions webserver/index.ts
@@ -1,9 +1,30 @@
import * as aws from "@pulumi/aws";
import * as webserver from "./webserver"; // use our custom component

(async () => {
let zones: string[] = (await aws.getAvailabilityZones()).names;
for (let i = 0; i < zones.length; i++) {
let server = webserver.createInstance("web-server-www-" + i, "t2.micro", zones[i]);
}
})();

// the type InstanceType contains friendly names for AWS instance sizes
let size: aws.ec2.InstanceType = "t2.micro";

// create a new security group for port 80
let group = new aws.ec2.SecurityGroup("web-secgrp", {
description: "Enable HTTP access",
ingress: [
{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
],
});

// (optional) create a simple web server using the startup script for the instance
// use the AWS metadata service to get the availability zone for the instance
let userData =
`#!/bin/bash
echo "Hello, World!\nInstance metadata:" > index.html
curl http://169.254.169.254/latest/meta-data/placement/availability-zone >> index.html
nohup python -m SimpleHTTPServer 80 &`;

let server = new aws.ec2.Instance("web-server-www", {
tags: { "Name": "web-server-www" },
instanceType: size,
securityGroups: [ group.name ], // reference the group object above
ami: aws.ec2.getLinuxAMI(size), // call built-in function (can also be custom)
userData: userData // set up a simple web server
});

server.publicDns.then(dns => console.log(`Server URL: http://${dns}`));
3 changes: 3 additions & 0 deletions webserver/tsconfig.json
Expand Up @@ -2,6 +2,9 @@
"compilerOptions": {
"outDir": "bin",
"target": "es6",
"lib": [
"es6"
],
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
Expand Down

0 comments on commit a1a34e9

Please sign in to comment.