Creating Multiple VMs

Now you will create multiple VM instances, each running the same Python webserver, across all AWS availability zones in your region. Replace the part of your code that creates the webserver and exports the resulting IP address and hostname with the following:

const ips: any[] = [];
const hostnames: any[] = [];
const azs = await aws.getAvailabilityZones()
for (const az of azs.names) {
    const server = new aws.ec2.Instance(`web-server-${az}`, {
        instanceType: "t3.micro",
        securityGroups: [ sg.name ],
        ami: ami,
        availabilityZone: az,
        userData: "#!/bin/bash\n"+
            `echo 'Hello, World -- from ${az}!' > index.html\n` +
            "nohup python -m SimpleHTTPServer 80 &",
        tags: { "Name": "web-server" },
    });
    ips.push(server.publicIp);
    hostnames.push(server.publicDns);
}

The index.ts file should now have the following contents - please note the wrapping with the async function!:

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

export = async () => {
    const ami = aws.getAmi({
        filters: [{ name: "name", values: ["amzn-ami-hvm-*-x86_64-ebs"] }],
        owners: [ "137112412989" ],
        mostRecent: true,
    }).then(ami => ami.id);

    const sg = new aws.ec2.SecurityGroup("web-secgrp", {
        ingress: [
            { protocol: "icmp", fromPort: 8, toPort: 0, cidrBlocks: ["0.0.0.0/0"] },
            { protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
        ],
    });

    const ips: any[] = [];
    const hostnames: any[] = [];
    const azs = await aws.getAvailabilityZones()
    for (const az of azs.names) {
        const server = new aws.ec2.Instance(`web-server-${az}`, {
            instanceType: "t3.micro",
            securityGroups: [ sg.name ],
            ami: ami,
            availabilityZone: az,
            userData: "#!/bin/bash\n"+
                `echo 'Hello, World -- from ${az}!' > index.html\n` +
                "nohup python -m SimpleHTTPServer 80 &",
            tags: { "Name": "web-server" },
        });
        ips.push(server.publicIp);
        hostnames.push(server.publicDns);
    }
    return {
        ips: ips,
        hostnames: hostnames,
    };
}

Now run a command to update your stack with the new resource definitions:

pulumi up

You will see output like the following:

Updating (dev):

     Type                 Name                   Status
     pulumi:pulumi:Stack  iac-workshop-dev
 +   ├─ aws:ec2:Instance  web-server-us-west-2a  created
 +   ├─ aws:ec2:Instance  web-server-us-west-2b  created
 +   ├─ aws:ec2:Instance  web-server-us-west-2c  created
 -   └─ aws:ec2:Instance  web-server             deleted

Outputs:
  + hostnames     : [
  +     [0]: "ec2-18-197-184-46.us-west-2.compute.amazonaws.com"
  +     [1]: "ec2-18-196-225-191.us-west-2.compute.amazonaws.com"
  +     [2]: "ec2-35-158-83-62.us-west-2.compute.amazonaws.com"
    ]
  + ips           : [
  +     [0]: "18.197.184.46"
  +     [1]: "18.196.225.191"
  +     [2]: "35.158.83.62"
    ]
  - publicHostname: "ec2-52-57-250-206.us-west-2.compute.amazonaws.com"
  - publicIp      : "52.57.250.206"

Resources:
    + 3 created
    - 1 deleted
    4 changes. 2 unchanged

Duration: 1m2s

Permalink: https://app.pulumi.com/workshops/ec2-workshop/dev/updates/2

Notice that your original server was deleted and new ones created in its place, because its name changed.

To test the changes, curl any of the resulting IP addresses or hostnames:

for i in {0..2}; do curl $(pulumi stack output hostnames | jq -r ".[${i}]"); done

The count of servers depends on the number of AZs in your region. Adjust the {0..2} accordingly.

The pulumi stack output command emits JSON serialized data — hence the use of the jq tool to extract a specific index. If you don’t have jq, don’t worry; simply copy-and-paste the hostname or IP address from the console output and curl that.

Note that the webserver number is included in its response:

Hello, World -- from us-west-2a!
Hello, World -- from us-west-2b!
Hello, World -- from us-west-2c!