Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
arsenvlad committed Dec 21, 2020
1 parent 1165b7c commit 2372d7b
Show file tree
Hide file tree
Showing 11 changed files with 412 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*private*
*.zip
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
# azure-vm-offer-hello-world-202012
# Azure Virtual Machine (VM) Offer - Hello World Example (December 2020)

This repo contains a simple "Hello World" style example of Azure Virtual Machine offer that is used in a video tutorial.

## Create Azure VM Image

### Create Azure VM Image with Packer

* [VHD Destination](packer/packer-vhd.md)

![Packer - VHD Destination](images/packer-vhd.png)

* [Shared Image Gallery Destination](packer/packer-sig.md)

![Packer - Shared Image Gallery Destination](images/packer-sig.png)

## Publish VM Offer in Azure Marketplace

<https://docs.microsoft.com/en-us/azure/marketplace/azure-vm-create>
Binary file added images/packer-sig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/packer-vhd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions packer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Create Azure VM Image with Packer

* [VHD Destination](packer-vhd.md)

![Packer - VHD Destination](../images/packer-vhd.png)

* [Shared Image Gallery Destination](packer-sig.md)

![Packer - Shared Image Gallery Destination](../images/packer-sig.png)
61 changes: 61 additions & 0 deletions packer/packer-sig-ubuntu.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"variables": {
"subscription_id": "{{env `AZURE_SUBSCRIPTION_ID`}}",
"tenant_id": "{{env `AZURE_TENANT_ID`}}",
"client_id": "{{env `AZURE_CLIENT_ID`}}",
"client_secret": "{{env `AZURE_CLIENT_SECRET`}}",
"location": "eastus2",
"sig_gallery_resource_group": "",
"sig_gallery_name": "",
"sig_image_name": "",
"sig_image_version": "1.0.0"
},
"sensitive-variables": ["client_secret"],
"builders": [{
"type": "azure-arm",
"subscription_id": "{{user `subscription_id`}}",
"tenant_id": "{{user `tenant_id`}}",
"client_id": "{{user `client_id`}}",
"client_secret": "{{user `client_secret`}}",

"os_type": "Linux",
"image_publisher": "Canonical",
"image_offer": "UbuntuServer",
"image_sku": "18.04-LTS",
"image_version": "latest",

"location": "{{user `location`}}",
"vm_size": "Standard_DS2_v2",
"temp_resource_group_name": "packer-rg",
"temp_compute_name": "packervm",
"private_virtual_network_with_public_ip": true,
"custom_data_file": "",
"polling_duration_timeout": "0h30m0s",

"managed_image_name": "packer-image",
"managed_image_resource_group_name": "{{user `sig_gallery_resource_group`}}",

"shared_image_gallery_destination": {
"subscription": "{{user `subscription_id`}}",
"resource_group": "{{user `sig_gallery_resource_group`}}",
"gallery_name": "{{user `sig_gallery_name`}}",
"image_name": "{{user `sig_image_name`}}",
"image_version": "{{user `sig_image_version`}}",
"replication_regions": ["{{user `location`}}"]
}
}
],
"provisioners": [{
"type": "shell",
"inline_shebang": "/bin/sh -x -e",
"execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
"inline": [
"apt-get update",
"apt-get upgrade -y",
"apt-get install -y nginx",
"mkdir -p /my_custom_folder",
"echo 'Hello from Packer' > /my_custom_folder/hello.txt",
"/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
]
}]
}
86 changes: 86 additions & 0 deletions packer/packer-sig.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Create Azure VM Image with Packer - Shared Image Gallery (SIG) Destination

## Prepare

Download Packer binary <https://www.packer.io/downloads>

Review Packer templates

* [packer-sig-ubuntu.json](packer-sig-ubuntu.json)

Set environment variables with credentials of Service Principal that has Contributor role on the Azure subscription

```bash
set AZURE_SUBSCRIPTION_ID=
set AZURE_TENANT_ID=
set AZURE_CLIENT_ID=
set AZURE_CLIENT_SECRET=
```

![Packer - SIG Destination](../images/packer-sig.png)

Create Shared Image Gallery or skip if want to use an existing one

```bash
# Create resource group
az group create --name avsig200 --location eastus2

# Create shared image gallery resource
az sig create --resource-group avsig200 --gallery-name avgallery200

# Create shared image gallery image definition
az sig image-definition create --resource-group avsig200 --gallery-name avgallery200 --gallery-image-definition avimage200 --os-type Linux --publisher avpublisher200 --offer avoffer200 --sku avsku200
```

**Execute Packer build** to create Shared Image Gallery image version

```bash
packer build -var location=eastus2 -var sig_gallery_resource_group=avsig200 -var sig_gallery_name=avgallery200 -var sig_image_name=avimage200 -var sig_image_version=1.0.0 packer-sig-ubuntu.json
```

Create test VM from the Shared Image Gallery image

```bash
# Create resource group for the test VM
az group create --name avtestvm200 --location eastus2

# Create test VM with public IP
az vm create --resource-group avtestvm200 --name ubuntuvm --image "/subscriptions/c9c8ae57-acdb-48a9-99f8-d57704f18dee/resourceGroups/avsig200/providers/Microsoft.Compute/galleries/avgallery200/images/avimage200/versions/1.0.0" --admin-username azureuser --admin-password "Password@123"
```

Run certification tool against the VM

* [Certification Test Tool for Azure Certified](https://www.microsoft.com/download/details.aspx?id=44299)
* [Using Self-Test API to validate VM images for publishing in Azure Marketplace](https://arsenvlad.medium.com/using-self-test-api-to-validate-vm-images-for-publishing-in-azure-marketplace-e7ac2e0b4d6e)

Generate VHD SAS URL from the Shared Gallery Image

> For more details and screenshots, see this [blog post](https://arsenvlad.medium.com/creating-vhd-azure-blob-sas-url-from-azure-managed-image-2be0e7c287f4) which shows how to use the same approach for creating VHD SAS URL from a managed image by converting it to Shared Image Gallery first.
```bash
# Create Azure Managed Disk from Shared Image Gallery
az disk create --resource-group avsig200 --location eastus2 --name my-disk-from-image --gallery-image-reference /subscriptions/c9c8ae57-acdb-48a9-99f8-d57704f18dee/resourceGroups/avsig200/providers/Microsoft.Compute/galleries/avgallery200/images/avimage200/versions/1.0.0

# Generate SAS URL for the Managed Disk
az disk grant-access --resource-group avsig200 --name my-disk-from-image --duration-in-seconds 36000 --access-level Read

# Copy Azure Managed Disk to Azure Blob Storage Container

# Create storage account
az storage account create --resource-group avsig200 --name avvhdstorage200 --location eastus2 --sku Standard_LRS --kind StorageV2 --access-tier Hot

# Create storage container
az storage container create --resource-group avsig200 --account-name avvhdstorage200 --name myvhds

# Create writable SAS URL for the container
az storage container generate-sas --account-name avvhdstorage200 --name myvhds --permissions acw --expiry "2020-12-01T00:00:00Z"

# Copy managed disk using its SAS URL to the container
azcopy copy "https://md-dcbqwqxfvbjb.blob.core.windows.net/f3gcv45nzg0z/abcd?sv=2018-03-28&sr=b&si=01897e7a-826c-4cd7-8229-0b0e1e30e5ec&sig=MhjTJ60QbJpegOhxLDHynHGkh935D6e7zpOyqIHd1gE%3D" "https://avvhdstorage200.blob.core.windows.net/myvhds/myimage1.vhd?se=2020-12-01T00%3A00%3A00Z&sp=acw&sv=2018-11-09&sr=c&sig=xIQxuK%2BfjUgAXSsXF%2B6fzY05GbNfUWuT3owl8LhhHTc%3D"

# Create SAS for the VHD to use in Partner Center
az storage container generate-sas --account-name avvhdstorage200 --name myvhds --permissions rl --start "2020-12-01T00:00:00Z" --expiry "2020-12-31T00:00:00Z"

# Append SAS token to the URL of the container to use in Azure Marketplace
# For example: https://avvhdstorage200.blob.core.windows.net/myvhds/myimage1.vhd?SAS_SIGNATURE_HERE
```
52 changes: 52 additions & 0 deletions packer/packer-vhd-centos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"variables": {
"subscription_id": "{{env `AZURE_SUBSCRIPTION_ID`}}",
"tenant_id": "{{env `AZURE_TENANT_ID`}}",
"client_id": "{{env `AZURE_CLIENT_ID`}}",
"client_secret": "{{env `AZURE_CLIENT_SECRET`}}",
"location": "eastus2",
"storage_resource_group": "",
"storage_account": ""
},
"sensitive-variables": ["client_secret"],
"builders": [{
"type": "azure-arm",
"subscription_id": "{{user `subscription_id`}}",
"tenant_id": "{{user `tenant_id`}}",
"client_id": "{{user `client_id`}}",
"client_secret": "{{user `client_secret`}}",

"os_type": "Linux",
"image_publisher": "OpenLogic",
"image_offer": "CentOS",
"image_sku": "8_2",
"image_version": "latest",

"location": "{{user `location`}}",
"vm_size": "Standard_DS2_v2",
"temp_resource_group_name": "packer-rg",
"temp_compute_name": "packervm",
"private_virtual_network_with_public_ip": true,
"custom_data_file": "",
"polling_duration_timeout": "0h30m0s",

"resource_group_name": "{{user `storage_resource_group`}}",
"storage_account": "{{user `storage_account`}}",
"capture_container_name": "packer",
"capture_name_prefix": "centos82"
}
],
"provisioners": [{
"type": "shell",
"inline_shebang": "/bin/sh -x -e",
"execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
"inline": [
"yum update",
"yum install epel-release",
"yum install nginx",
"mkdir -p /my_custom_folder",
"echo 'Hello from Packer' > /my_custom_folder/hello.txt",
"waagent -force -deprovision+user && export HISTSIZE=0 && sync"
]
}]
}
52 changes: 52 additions & 0 deletions packer/packer-vhd-ubuntu.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"variables": {
"subscription_id": "{{env `AZURE_SUBSCRIPTION_ID`}}",
"tenant_id": "{{env `AZURE_TENANT_ID`}}",
"client_id": "{{env `AZURE_CLIENT_ID`}}",
"client_secret": "{{env `AZURE_CLIENT_SECRET`}}",
"location": "eastus2",
"storage_resource_group": "",
"storage_account": ""
},
"sensitive-variables": ["client_secret"],
"builders": [{
"type": "azure-arm",
"subscription_id": "{{user `subscription_id`}}",
"tenant_id": "{{user `tenant_id`}}",
"client_id": "{{user `client_id`}}",
"client_secret": "{{user `client_secret`}}",

"os_type": "Linux",
"image_publisher": "Canonical",
"image_offer": "UbuntuServer",
"image_sku": "18.04-LTS",
"image_version": "latest",

"location": "{{user `location`}}",
"vm_size": "Standard_DS2_v2",
"temp_resource_group_name": "packer-rg",
"temp_compute_name": "packervm",
"private_virtual_network_with_public_ip": true,
"custom_data_file": "",
"polling_duration_timeout": "0h30m0s",

"resource_group_name": "{{user `storage_resource_group`}}",
"storage_account": "{{user `storage_account`}}",
"capture_container_name": "packer",
"capture_name_prefix": "ubuntu1804"
}
],
"provisioners": [{
"type": "shell",
"inline_shebang": "/bin/sh -x -e",
"execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
"inline": [
"apt-get update",
"apt-get upgrade -y",
"apt-get install -y nginx",
"mkdir -p /my_custom_folder",
"echo 'Hello from Packer' > /my_custom_folder/hello.txt",
"/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
]
}]
}
56 changes: 56 additions & 0 deletions packer/packer-vhd-windows.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"variables": {
"subscription_id": "{{env `AZURE_SUBSCRIPTION_ID`}}",
"tenant_id": "{{env `AZURE_TENANT_ID`}}",
"client_id": "{{env `AZURE_CLIENT_ID`}}",
"client_secret": "{{env `AZURE_CLIENT_SECRET`}}",
"location": "eastus2",
"storage_resource_group": "",
"storage_account": ""
},
"sensitive-variables": ["client_secret"],
"builders": [{
"type": "azure-arm",
"subscription_id": "{{user `subscription_id`}}",
"tenant_id": "{{user `tenant_id`}}",
"client_id": "{{user `client_id`}}",
"client_secret": "{{user `client_secret`}}",

"os_type": "Windows",
"image_publisher": "MicrosoftWindowsServer",
"image_offer": "WindowsServer",
"image_sku": "2019-Datacenter",
"image_version": "latest",

"communicator": "winrm",
"winrm_use_ssl": true,
"winrm_insecure": true,
"winrm_timeout": "5m",

"location": "{{user `location`}}",
"vm_size": "Standard_DS2_v2",
"temp_resource_group_name": "packer-rg",
"temp_compute_name": "packervm",
"private_virtual_network_with_public_ip": true,
"custom_data_file": "",
"polling_duration_timeout": "0h30m0s",

"resource_group_name": "{{user `storage_resource_group`}}",
"storage_account": "{{user `storage_account`}}",
"capture_container_name": "packer",
"capture_name_prefix": "ubuntu1804"
}
],
"provisioners": [{
"type": "powershell",
"inline": [
"Add-WindowsFeature Web-Server",
"while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
"while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
"mkdir C:\\my_custom_folder\\",
"echo Hello from Packer > C:\\my_custom_folder\\hello.txt",
"& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit",
"while ($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }"
]
}]
}
Loading

0 comments on commit 2372d7b

Please sign in to comment.