Coder Social home page Coder Social logo

compute-python-msi-vm's Introduction

page_type languages products description urlFragment
sample
python
azure
This sample explains how to create a VM with Managed Service Identity enabled.
compute-python-msi-vm

Create a VM with MSI authentication enabled

This sample explains how to create a VM with Managed Service Identity enabled. This sample covers the two types of MSI scenarios:

  • System Assigned Identity: the identity is created by ARM on VM creation/update
  • User Assigned Identity: the identity is created and managed by the user, and assigned during VM creation/update

On this page

Run this sample

  1. If you don't already have it, install Python.

  2. We recommend to use a virtual environnement to run this example, but it's not mandatory. You can initialize a virtualenv this way:

    pip install virtualenv
    virtualenv mytestenv
    cd mytestenv
    source bin/activate
    
  3. Clone the repository.

    git clone https://github.com/Azure-Samples/compute-python-msi-vm.git
    
  4. Install the dependencies using pip.

    cd compute-python-msi-vm
    pip install -r requirements.txt
    
  5. Create an Azure service principal either through Azure CLI, PowerShell or the portal.

    Important note: to be able to run this sample, your Service Principal MUST have "Owner" role enabled, or at least the "Microsoft.Authorization/*/write" permission. Learn more about Built-in Role for Azure

  6. Export these environment variables into your current shell.

    export AZURE_TENANT_ID={your tenant id}
    export AZURE_CLIENT_ID={your client id}
    export AZURE_CLIENT_SECRET={your client secret}
    export AZURE_SUBSCRIPTION_ID={your subscription id}
    
  7. Run the sample.

    python example.py
    

What is example.py doing?

The sample creates a VM with MSI creation. Then assign permission to that token. Finally it installs the VM extension necessary to get this token from inside the VM. It starts by setting up several clients using your subscription and credentials.

import os
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.authorization import AuthorizationManagementClient

subscription_id = os.environ.get(
    'AZURE_SUBSCRIPTION_ID',
    '11111111-1111-1111-1111-111111111111') # your Azure Subscription Id
credentials = ServicePrincipalCredentials(
    client_id=os.environ['AZURE_CLIENT_ID'],
    secret=os.environ['AZURE_CLIENT_SECRET'],
    tenant=os.environ['AZURE_TENANT_ID']
)
resource_client = ResourceManagementClient(credentials, subscription_id)
compute_client = ComputeManagementClient(credentials, subscription_id)
network_client = NetworkManagementClient(credentials, subscription_id)
authorization_client = AuthorizationManagementClient(credentials, subscription_id)

There are a couple of supporting functions (print_item and print_properties) that print a resource group and it's properties.

Preliminary operations

This example setup some preliminary components that are no the topic of this sample and do not differ from regular scenarios:

  • A Resource Group
  • A Virtual Network
  • A Subnet
  • A Public IP
  • A Network Interface

For details about creation of these components, you can refer to the generic samples:

Create a User Assigned Identity

You do NOT require this step if you just want to use System Assigned Identity.

Creating a User Assigned identity is simple (requires package azure-mgmt-msi):

msi_client = ManagedServiceIdentityClient(credentials, subscription_id)
user_assigned_identity = msi_client.user_assigned_identities.create_or_update(
    GROUP_NAME,
    "myMsiIdentity", # Any name, just a human readable ID
    LOCATION
)

Create a VM with MSI creation

You can create a VM with both User Assigned and System Assigned at the same time, or only one of them. In System Assigned, only one attribute is necessary to ask Azure to create a MSI id. In User Assigned, you just need to provide the ID of the User Assigned identity you just created:

params_identity = {}
if USER_ASSIGNED_IDENTITY and SYSTEM_ASSIGNED_IDENTITY:
    params_identity['type'] = ResourceIdentityType.system_assigned_user_assigned # Enum value for both
    params_identity['identity_ids'] = [
        user_assigned_identity.id
    ]
elif USER_ASSIGNED_IDENTITY: # User Assigned only
    params_identity['type'] = ResourceIdentityType.user_assigned
    params_identity['identity_ids'] = [
        user_assigned_identity.id
    ]
elif SYSTEM_ASSIGNED_IDENTITY: # System assigned only
    params_identity['type'] = ResourceIdentityType.system_assigned

params_create = {
    'location': LOCATION,
    'os_profile': get_os_profile(),
    'hardware_profile': get_hardware_profile(),
    'network_profile': get_network_profile(nic.id),
    'storage_profile': get_storage_profile(),
    # Activate MSI on that VM
    'identity': params_identity
}

vm_poller = compute_client.virtual_machines.create_or_update(
    GROUP_NAME,
    VM_NAME,
    params_create,
)
vm_result = vm_poller.result()

Role assignement to the MSI credentials

By default, MSI identities does not have any permissions and will be unable to do anything.

This section shows how to get the role id of the built-in role "Contributor" and to assign it with the scope "Resource Group" to a MSI identity.

msi_accounts_to_assign = []
if SYSTEM_ASSIGNED_IDENTITY:
    msi_accounts_to_assign.append(vm_result.identity.principal_id)
if USER_ASSIGNED_IDENTITY:
    msi_accounts_to_assign.append(user_assigned_identity.principal_id)

# Get "Contributor" built-in role as a RoleDefinition object
role_name = 'Contributor'
roles = list(authorization_client.role_definitions.list(
    resource_group.id,
    filter="roleName eq '{}'".format(role_name)
))
assert len(roles) == 1
contributor_role = roles[0]

# Add RG scope to the MSI token
for msi_identity in msi_accounts_to_assign:

    role_assignment = authorization_client.role_assignments.create(
        resource_group.id,
        uuid.uuid4(), # Role assignment random name
        {
            'role_definition_id': contributor_role.id,
            'principal_id': msi_identity
        }
    )

Usage

You can now connect to the VM and use the MSI credentials directly, without passing credentials to the VM.

More details on how to use MSI with SDK can be found in the MSI usage sample

Once the Azure VM has been created, you can verify the IMDS endpoint, which serves the token request, is working by making a HTTP get request to http://169.254.169.254/metadata/instance.

Delete a resource group

delete_async_operation = client.resource_groups.delete('azure-msi-sample-group')
delete_async_operation.wait()

compute-python-msi-vm's People

Contributors

lmazuel avatar microsoftopensource avatar msftgits avatar sptramer avatar v-rajagt-zz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

compute-python-msi-vm's Issues

May need update for 2018 version of API or explicitly say only for 2017 version of the API

Please provide us with the following information:

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [ X ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

Any log messages given by the failure

Expected/desired behavior

OS and Version?

Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)

Versions

Mention any other details that might be useful

The identity creation seems to be based on 2017 version of API but does not explicitly say so - even though this has been updated in 2019.

The 2018 version changed to "userAssignedIdentities" as the key value and the data structure changed from List to Dict. See https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/qs-configure-template-windows-vm. Therefore your identity would be create in python as this:

    params_identity = {}
    params_identity['type'] = ResourceIdentityType.user_assigned
    params_identity['userAssignedIdentities'] = {
        "myIdentity":{}
    }

Thanks! We'll be in touch soon.

Do we need to install the MSI extension any more?

Hi,

Looking at some of the other documentation on authenticating using MSI from an MSI enabled Azure VM, it appears that we no longer require the localhost REST service running on 50342 in the MSI enabled VM. Instead, we can obtain oauth tokens using from this endpoint as documented here.
Thus, it seems we no longer need to install the MSI REST service on azure VM. Infact I heard the localhost service will soon be deprecated? Please confirm.

Thanks.

[Action Needed] This repo is inactive

This GitHub repository has been identified as a candidate for archival

This repository has had no activity for more than 2 years. Long periods of inactivity present security and code hygiene risks. Archiving will not prevent users from viewing or forking the code. A banner will appear on the repository alerting users that the repository is archived.

Please see https://aka.ms/sunsetting-faq to learn more about this process.

Action

✍️

❗**If this repository is still actively maintained, please simply close this issue. Closing an issue on a repository is considered activity and the repository will not be archived.🔒

If you take no action, this repository is still inactive 30 days from today it will be automatically archived..

Need more help? 🖐️

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.