Skip to main content

Azure Getting Started

Let's create a simple infrastructure with the following resources:

First of all, ensure all the Azure prerequisites has been met: AzureRequirements

Getting the code#

Install the grucloud command line utility: gc

npm i -g @grucloud/core

Clone the code and go to one of the azure examples:

git clone git@github.com:grucloud/grucloud.git
cd grucloud/examples/azure
npm install

Environment#

Create default.env and set the correct values:

TENANT_ID=
SUBSCRIPTION_ID=
APP_ID=
PASSWORD=
MACHINE_ADMIN_USERNAME=
MACHINE_ADMIN_PASSWORD=

See AzureRequirements to retrieve these informations

Config#

Edit config.js and set the location:

module.exports = () => ({
location: "uksouth",
});

To find out the list of locations:

az account list-locations -o table

Now it is time to edit the infrastructure iac.js file that describes the architecture.

const assert = require("assert");
const { AzureProvider } = require("@grucloud/provider-azure");
exports.createStack = async ({ config, stage }) => {
assert(stage);
// Create an Azure provider
const provider = AzureProvider({ config });
// https://docs.microsoft.com/en-us/rest/api/apimanagement/2019-12-01/apimanagementservice/createorupdate
const rg = provider.makeResourceGroup({
name: `resource-group-${stage}`,
});
// https://docs.microsoft.com/en-us/rest/api/virtualnetwork/virtualnetworks/createorupdate#request-body
const vnet = provider.makeVirtualNetwork({
name: `virtual-network-${stage}`,
dependencies: { resourceGroup: rg },
properties: () => ({
properties: {
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
subnets: [
{
name: `subnet-${stage}`,
properties: {
addressPrefix: "10.0.0.0/24",
},
},
],
},
}),
});
// https://docs.microsoft.com/en-us/rest/api/virtualnetwork/networksecuritygroups/createorupdate#request-body
const sg = provider.makeSecurityGroup({
name: `security-group-${stage}`,
dependencies: { resourceGroup: rg },
properties: () => ({
properties: {
securityRules: [
{
name: "SSH",
properties: {
access: "Allow",
direction: "Inbound",
protocol: "Tcp",
destinationPortRange: "22",
destinationAddressPrefix: "*",
sourcePortRange: "*",
sourceAddressPrefix: "*",
priority: 1000,
},
},
],
},
}),
});
// https://docs.microsoft.com/en-us/rest/api/virtualnetwork/publicipaddresses/createorupdate#request-body
const publicIpAddress = provider.makePublicIpAddress({
name: `ip-${stage}`,
dependencies: {
resourceGroup: rg,
},
properties: () => ({
properties: {
publicIPAllocationMethod: "Dynamic",
},
}),
});
// https://docs.microsoft.com/en-us/rest/api/virtualnetwork/networkinterfaces/createorupdate#request-body
const networkInterface = provider.makeNetworkInterface({
name: `network-interface-${stage}`,
dependencies: {
resourceGroup: rg,
virtualNetwork: vnet,
securityGroup: sg,
subnet: `subnet-${stage}`,
publicIpAddress,
},
properties: () => ({
properties: {
ipConfigurations: [
{
name: "ipconfig",
properties: {
privateIPAllocationMethod: "Dynamic",
},
},
],
},
}),
});
const { MACHINE_ADMIN_USERNAME, MACHINE_ADMIN_PASSWORD } = process.env;
assert(MACHINE_ADMIN_USERNAME);
assert(MACHINE_ADMIN_PASSWORD);
// https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/createorupdate
const vm = provider.makeVirtualMachine({
name: `vm-${stage}`,
dependencies: {
resourceGroup: rg,
networkInterface,
},
properties: () => ({
properties: {
hardwareProfile: {
vmSize: "Standard_A1_v2",
},
storageProfile: {
imageReference: {
// az vm image list
offer: "UbuntuServer",
publisher: "Canonical",
sku: "18.04-LTS",
version: "latest",
},
},
osProfile: {
adminUsername: MACHINE_ADMIN_USERNAME,
computerName: "myVM",
adminPassword: MACHINE_ADMIN_PASSWORD,
},
},
}),
});
return { provider };
};

Plan#

Find out which resources are going to be allocated:

gc plan

Deploy#

Happy with the expected plan ? Deploy it now:

gc apply

List#

List the available resources and display a diagram with:

gc list --graph

Destroy#

Time to destroy the resouces allocated:

gc destroy