Skip to content

Commit

Permalink
Add a Python Azure Webserver example (pulumi#236)
Browse files Browse the repository at this point in the history
* Add a Python Azure Webserver example

* Add README.md

* fix numbering

* Fix indentation in readme

* Update README now that this works

* Fix custom data + use simpler pattern for data source

* Format code

* Add test

* Fix syntax error
  • Loading branch information
swgillespie committed Mar 21, 2019
1 parent f93239b commit a0813b9
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 0 deletions.
3 changes: 3 additions & 0 deletions azure-py-webserver/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: azure-py-webserver
runtime: python
description: An Azure example using Python to provision a webserver
138 changes: 138 additions & 0 deletions azure-py-webserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new)

# Azure Web Server example in Python

This example deploys an Azure Virtual Machine and starts a HTTP server on it.

## Prerequisites

1. [Install Pulumi](https://pulumi.io/install/)
1. [Configure Pulumi for Azure](https://pulumi.io/quickstart/azure/setup.html)
1. [Configure Pulumi for Python](https://pulumi.io/reference/python.html)

## Deploying and running the program

1. Set up a virtual Python environment and install dependencies

```
$ virtualenv -p python3 venv
$ source venv/bin/activate
$ pip install -r requirements.txt
```

1. Create a new stack:

```
$ pulumi stack init azure-py-webserver
```

1. Set the Azure environment:

```
$ pulumi config set azure:environment public
```

1. Set the required configuration for this example. This example requires you to supply a username and password to
the virtual machine that we are going to create.

```
$ pulumi config set azure-web:username myusername
```

The password is a secret, so we can ask Pulumi to encrypt the configuration:

```
$ pulumi config set --secret azure-web:password Hunter2hunter2
```

1. Run `pulumi up` to preview and deploy the changes:

```
$ pulumi update
Previewing update (azuredev):
Type Name Plan
+ pulumi:pulumi:Stack azure-py-webserver-azuredev create
+ ├─ azure:core:ResourceGroup server create
+ ├─ azure:network:VirtualNetwork server-network create
+ ├─ azure:network:PublicIp server-ip create
+ ├─ azure:network:Subnet server-subnet create
+ ├─ azure:network:NetworkInterface server-nic create
+ └─ azure:compute:VirtualMachine server-vm create
Resources:
+ 7 to create
Do you want to perform this update? yes
Updating (azuredev):
Type Name Status
+ pulumi:pulumi:Stack azure-py-webserver-azuredev created
+ ├─ azure:core:ResourceGroup server created
+ ├─ azure:network:VirtualNetwork server-network created
+ ├─ azure:network:PublicIp server-ip created
+ ├─ azure:network:Subnet server-subnet created
+ ├─ azure:network:NetworkInterface server-nic created
+ └─ azure:compute:VirtualMachine server-vm created
Outputs:
public_ip: "137.117.15.111"
Resources:
+ 7 created
Duration: 2m55s
Permalink: https://app.pulumi.com/swgillespie/azure-py-webserver/azuredev/updates/3
```

1. Get the IP address of the newly-created instance from the stack's outputs:

```
$ pulumi stack output public_ip
137.117.15.111
```

1. Check to see that your server is now running:

```
$ curl http:https://$(pulumi stack output public_ip)
Hello, World!
```

1. Destroy the stack:

```
▶ pulumi destroy --yes
Previewing destroy (azuredev):
Type Name Plan
- pulumi:pulumi:Stack azure-py-webserver-azuredev delete
- ├─ azure:compute:VirtualMachine server-vm delete
- ├─ azure:network:NetworkInterface server-nic delete
- ├─ azure:network:Subnet server-subnet delete
- ├─ azure:network:PublicIp server-ip delete
- ├─ azure:network:VirtualNetwork server-network delete
- └─ azure:core:ResourceGroup server delete
Resources:
- 7 to delete
Destroying (azuredev):
Type Name Status
- pulumi:pulumi:Stack azure-py-webserver-azuredev deleted
- ├─ azure:compute:VirtualMachine server-vm deleted
- ├─ azure:network:NetworkInterface server-nic deleted
- ├─ azure:network:Subnet server-subnet deleted
- ├─ azure:network:VirtualNetwork server-network deleted
- ├─ azure:network:PublicIp server-ip deleted
- └─ azure:core:ResourceGroup server deleted
Resources:
- 7 deleted
Duration: 3m49s
Permalink: https://app.pulumi.com/swgillespie/azure-py-webserver/azuredev/updates/4
```
79 changes: 79 additions & 0 deletions azure-py-webserver/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import pulumi
from pulumi import Output
from pulumi_azure import core, compute, network

config = pulumi.Config("azure-web")
username = config.require("username")
password = config.require("password")

resource_group = core.ResourceGroup("server", location="West US")
net = network.VirtualNetwork(
"server-network",
resource_group_name=resource_group.name,
location=resource_group.location,
address_spaces=["10.0.0.0/16"],
subnets=[{
"name": "default",
"address_prefix": "10.0.1.0/24",
}])

subnet = network.Subnet(
"server-subnet",
resource_group_name=resource_group.name,
virtual_network_name=net.name,
address_prefix="10.0.2.0/24")
public_ip = network.PublicIp(
"server-ip",
resource_group_name=resource_group.name,
location=resource_group.location,
allocation_method="Dynamic")

network_iface = network.NetworkInterface(
"server-nic",
resource_group_name=resource_group.name,
location=resource_group.location,
ip_configurations=[{
"name": "webserveripcfg",
"subnet_id": subnet.id,
"private_ip_address_allocation": "Dynamic",
"public_ip_address_id": public_ip.id,
}])

userdata = """#!/bin/bash
echo "Hello, World!" > index.html
nohup python -m SimpleHTTPServer 80 &"""

vm = compute.VirtualMachine(
"server-vm",
resource_group_name=resource_group.name,
location=resource_group.location,
network_interface_ids=[network_iface.id],
vm_size="Standard_A0",
delete_data_disks_on_termination=True,
delete_os_disk_on_termination=True,
os_profile={
"computer_name": "hostname",
"admin_username": username,
"admin_password": password,
"custom_data": userdata,
},
os_profile_linux_config={
"disable_password_authentication": False,
},
storage_os_disk={
"create_option": "FromImage",
"name": "myosdisk1",
},
storage_image_reference={
"publisher": "canonical",
"offer": "UbuntuServer",
"sku": "16.04-LTS",
"version": "latest",
})

combined_output = Output.all(vm.id, public_ip.name,
public_ip.resource_group_name)
public_ip_addr = combined_output.apply(
lambda lst: network.get_public_ip(name=lst[1], resource_group_name=lst[2]))
pulumi.export("public_ip", public_ip_addr.ip_address)
2 changes: 2 additions & 0 deletions azure-py-webserver/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pulumi>=0.17.2
pulumi_azure>=0.17.3
11 changes: 11 additions & 0 deletions misc/test/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,17 @@ func TestExamples(t *testing.T) {
// })
// },
}),
base.With(integration.ProgramTestOptions{
Dir: path.Join(cwd, "..", "..", "azure-py-webserver"),
Config: map[string]string{
"azure:environment": azureEnviron,
"azure-web:username": "myusername",
"azure-web:password": "Hunter2hunter2",
},
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
assertHTTPHelloWorld(t, stack.Outputs["public_ip"])
},
}),
// TODO: This test fails due to a bug in the Terraform Azure provider in which the
// service principal is not available when attempting to create the K8s cluster.
// See the azure-ts-aks-example readme for more detail.
Expand Down

0 comments on commit a0813b9

Please sign in to comment.