教程:使用 Ansible 从 Azure 共享映像库创建 VM 或虚拟机规模集

重要

要运行本文章中的示例剧本,需使用 Ansible 2.9(或更高版本)。

共享映像库 是一项服务,可用于轻松管理、共享和组织自定义托管映像。 此功能适用于维护和共享多个映像的方案。 可以在订阅之间以及 Microsoft Entra 租户之间共享自定义映像。 还可以将映像复制到多个区域,以便更快扩展部署。

在这篇文章中,你将学会如何:

  • 创建通用 VM 和自定义映像
  • 创建共享映像库
  • 创建共享映像和映像版本
  • 使用通用映像创建 VM
  • 使用通用映像创建虚拟机规模集
  • 获取有关共享映像库、映像及其版本的信息。

先决条件

  • Azure 订阅:如果没有 Azure 订阅,请在开始之前创建 一个免费帐户

获取示例剧本

可通过以下两种方式获取完整的剧本示例集:

  • 下载 SIG 文件夹 并将其保存到本地计算机。
  • 为每个部分创建新文件,并复制其中的示例 playbook。

vars.yml 文件包含本教程所有示例剧本使用的变量。 可以编辑文件以提供唯一名称和值。

第一个示例剧本 00-prerequisites.yml 创建了完成本教程所需的所有内容。

  • 资源组,它是在其中部署和管理 Azure 资源的逻辑容器。
  • 虚拟网络;子;VM 的公共 IP 地址和网络接口卡。
  • 用于创建通用映像的源虚拟机。
- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
    - name: Create resource group if doesn't exist
      azure_rm_resourcegroup:
        name: "{{ resource_group }}"
        location: "{{ location }}"
    
    - name: Create virtual network
      azure_rm_virtualnetwork:
        resource_group: "{{ resource_group }}"
        name: "{{ virtual_network_name }}"
        address_prefixes: "10.0.0.0/16"

    - name: Add subnet
      azure_rm_subnet:
        resource_group: "{{ resource_group }}"
        name: "{{ subnet_name }}"
        address_prefix: "10.0.1.0/24"
        virtual_network: "{{ virtual_network_name }}"

    - name: Create public IP address
      azure_rm_publicipaddress:
        resource_group: "{{ resource_group }}"
        allocation_method: Static
        name: "{{ ip_name }}"

    - name: Create virtual network interface cards for VM A and B
      azure_rm_networkinterface:
        resource_group: "{{ resource_group }}"
        name: "{{ network_interface_name }}"
        virtual_network: "{{ virtual_network_name }}"
        subnet: "{{ subnet_name }}"

    - name: Create VM
      azure_rm_virtualmachine:
        resource_group: "{{ resource_group }}"
        name: "{{ source_vm_name }}"
        admin_username: testuser
        admin_password: "Password1234!"
        vm_size: Standard_B1ms
        network_interfaces: "{{ network_interface_name }}"
        image:
          offer: UbuntuServer
          publisher: Canonical
          sku: 16.04-LTS
          version: latest

运行 playbook 使用 ansible-playbook

ansible-playbook 00-prerequisites.yml

Azure 门户中,检查指定的 vars.yml 资源组以查看新虚拟机和已创建的各种资源。

通用化 VM 并创建自定义映像

下一个 playbook 01a-create-generalized-image.yml将上一步中创建的源 VM 进行泛化,然后基于它创建一个自定义映像。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
    - name: Generalize VM
      azure_rm_virtualmachine:
        resource_group: "{{ resource_group }}"
        name: "{{ source_vm_name }}"
        generalized: yes

    - name: Create custom image
      azure_rm_image:
        resource_group: "{{ resource_group }}"
        name: "{{ image_name }}"
        source: "{{ source_vm_name }}"

运行 playbook 使用 ansible-playbook

ansible-playbook 01a-create-generalized-image.yml

检查你的资源组,并确保 testimagea 在资源组中出现。

映像库是用于共享和管理映像的存储库。 示例 playbook 代码02-create-shared-image-gallery.yml在您的资源组中创建共享映像库。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
    - name: Create shared image gallery
      azure_rm_gallery:
        resource_group: "{{ resource_group }}"
        name: "{{ shared_gallery_name }}"
        location: "{{ location }}"
        description: This is the gallery description.

运行 playbook 使用 ansible-playbook

ansible-playbook 02-create-shared-image-gallery.yml

现在,您在资源组中已经可以看到一个新的图库myGallery

创建共享映像和映像版本

下一个操作手册将创建03a-create-shared-image-generalized.yml映像定义和映像版本。

映像定义包括映像类型(Windows 或 Linux)、发行说明以及最小和最大内存要求。 映像版本指的是图片的版本。 图库、映像定义和映像版本帮助你将映像按逻辑组进行组织。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
    - name: Create shared image
      azure_rm_galleryimage:
        resource_group: "{{ resource_group }}"
        gallery_name: "{{ shared_gallery_name }}"
        name: "{{ shared_image_name }}"
        location: "{{ location }}"
        os_type: linux
        os_state: generalized
        identifier:
          publisher: myPublisherName
          offer: myOfferName
          sku: mySkuName
        description: Image description
    
    - name: Create or update a simple gallery image version.
      azure_rm_galleryimageversion:
        resource_group: "{{ resource_group }}"
        gallery_name: "{{ shared_gallery_name }}"
        gallery_image_name: "{{ shared_image_name }}"
        name: "{{ shared_image_version }}"
        location: "{{ location }}"
        publishing_profile:
          end_of_life_date: "2020-10-01t00:00:00+00:00"
          exclude_from_latest: yes
          replica_count: 3
          storage_account_type: Standard_LRS
          target_regions:
            - name: West US
              regional_replica_count: 1
            - name: East US
              regional_replica_count: 2
              storage_account_type: Standard_ZRS
          managed_image:
            name: "{{ image_name }}"
            resource_group: "{{ resource_group }}"
      register: output

    - debug:
        var: output

运行 playbook 使用 ansible-playbook

ansible-playbook 03a-create-shared-image-generalized.yml

您的资源组现在包含一个映像定义和一个用于您库的映像版本。

基于通用映像创建 VM

最后,运行 04a-create-vm-using-generalized-image.yml 以基于在上一步中创建的通用映像创建 VM。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
  - name: Create VM using shared image
    azure_rm_virtualmachine:
      resource_group: "{{ resource_group }}"
      name: "{{ vm_name }}"
      vm_size: Standard_DS1_v2
      admin_username: adminUser
      admin_password: PassWord01
      managed_disk_type: Standard_LRS
      image:
        id: "/subscriptions/{{ lookup('env', 'AZURE_SUBSCRIPTION_ID') }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Compute/galleries/{{ shared_gallery_name }}/images/{{ shared_image_name }}/versions/{{ shared_image_version }}"

运行 playbook 使用 ansible-playbook

ansible-playbook 04a-create-vm-using-generalized-image.yml

基于通用映像创建虚拟机规模集

您还可以基于已通用化的镜像创建一个虚拟机规模集。 运行 05a-create-vmss-using-generalized-image.yml 来实现这一操作。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
  - name: Create a virtual machine scale set using a shared image
    azure_rm_virtualmachinescaleset:
      resource_group: "{{ resource_group }}"
      name: "{{ vmss_name }}"
      vm_size: Standard_DS1_v2
      admin_username: adminUser
      admin_password: PassWord01
      capacity: 2
      virtual_network_name: "{{ virtual_network_name }}"
      upgrade_policy: Manual
      subnet_name: "{{ subnet_name }}"
      managed_disk_type: Standard_LRS
      image:
        id: "/subscriptions/{{ lookup('env', 'AZURE_SUBSCRIPTION_ID') }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Compute/galleries/{{ shared_gallery_name }}/images/{{ shared_image_name }}/versions/{{ shared_image_version }}"

运行 playbook 使用 ansible-playbook

ansible-playbook 05a-create-vmss-using-generalized-image.yml

可以通过运行 06-get-info.yml 来获取有关图库、映像定义和版本的信息。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
  - name: Get Shared Image Gallery information
    azure_rm_gallery_info:
      resource_group: "{{ resource_group }}"
      name: "{{ shared_gallery_name }}"
  - name: Get shared image information
    azure_rm_galleryimage_info:
      resource_group: "{{ resource_group }}"
      gallery_name: "{{ shared_gallery_name }}"
      name: "{{ shared_image_name }}"
  - name: Get Shared Image Gallery image version information
    azure_rm_galleryimageversion_info:
      resource_group: "{{ resource_group }}"
      gallery_name: "{{ shared_gallery_name }}"
      gallery_image_name: "{{ shared_image_name }}"
      name: "{{ shared_image_version }}"

运行 playbook 使用 ansible-playbook

ansible-playbook 06-get-info.yml

删除共享映像

若要删除画廊资源,请参阅示例操作手册 07-delete-gallery.yml。 按相反顺序删除资源。 首先删除映像版本。 删除所有映像版本后,可以删除映像定义。 删除所有映像定义后,可以删除图库。

- hosts: localhost
  connection: local
  vars_files:
    - ./vars.yml

  tasks:
  - name: Delete gallery image version.
    azure_rm_galleryimageversion:
      resource_group: "{{ resource_group }}"
      gallery_name: "{{ shared_gallery_name }}"
      gallery_image_name: "{{ shared_image_name }}"
      name: "{{ shared_image_version }}"
      state: absent

  - name: Delete gallery image
    azure_rm_galleryimage:
      resource_group: "{{ resource_group }}"
      gallery_name: "{{ shared_gallery_name }}"
      name: "{{ shared_image_name }}"
      state: absent

  - name: Delete a simple gallery.
    azure_rm_gallery:
      resource_group: "{{ resource_group }}"
      name: "{{ shared_gallery_name }}"
      state: absent

运行 playbook 使用 ansible-playbook

ansible-playbook 07-delete-gallery.yml

清理资源

  1. 将以下代码保存为 delete_rg.yml.

    ---
    - hosts: localhost
      tasks:
        - name: Deleting resource group - "{{ name }}"
          azure_rm_resourcegroup:
            name: "{{ name }}"
            state: absent
          register: rg
        - debug:
            var: rg
    
  2. 使用 ansible-playbook 命令来运行 playbook。 将占位符替换为要删除的资源组的名称。 资源组中的所有资源都将被删除。

    ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"
    

    要点

    • 因为 playbook 中的register变量和debug部分,命令完成后会显示结果。

后续步骤