{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# Azure CLI Account Setup for Azure Resource Manager (ARM)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Azure CLI provides an easy way to setup an account for Azure Resource Manager (ARM) and furthermore creates an new service principal for the Simple Azure access. In this tutorial, we use IPython helper (!) to run Azure CLI. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interactive Login Azure Portal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "azure cli tool asks you to open a web browser and sign in the azure portal to authenciate. The following command ``azure login`` will guide you to the page https://aka.ms/devicelogin with a unique one-time login verification code.\n", "You will be asked to type the code in your browser to complete the login. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**NOTE** Run all cells step-by-step with instructions to complete Azure Account Setup." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1G\u001b[0JMicrosoft Azure CLI would like to collect data about how users use CLI\n", "commands and some problems they encounter. Microsoft uses this information\n", "to improve our CLI commands. Participation is voluntary and when you\n", "choose to participate your device automatically sends information to\n", "Microsoft about how you use Azure CLI. \n", "\n", "If you choose to participate, you can stop at any time later by using Azure\n", "CLI as follows: \n", "1. Use the azure telemetry command to turn the feature Off. \n", "To disable data collection, execute: azure telemetry --disable\n", "\n", "If you choose to not participate, you can enable at any time later by using\n", "Azure CLI as follows: \n", "1. Use the azure telemetry command to turn the feature On. \n", "To enable data collection, execute: azure telemetry --enable\n", "\n", "Select y to enable data collection :(y/n) \u001b[43G\u001b[10A\n", "You choose to participate in Microsoft Azure CLI data collection.\n", "\n", "\n", "\u001b[32minfo\u001b[39m: Executing command \u001b[1mlogin\u001b[22m\n", "\u001b[36m\\\u001b[39m\u001b[32minfo\u001b[39m: To sign in, use a web browser to open the page https://aka.ms/devicelogin. Enter the code EVAMBVQE4 to authenticate.\n", "\u001b[36m|\u001b[39m\u001b[32minfo\u001b[39m: Added subscription Simple-Azure-Subscription\n", "\u001b[32minfo\u001b[39m: Setting subscription \"Simple-Azure-Subscription\" as default\n", "+\n", "\u001b[32minfo\u001b[39m: \u001b[1mlogin\u001b[22m command \u001b[1m\u001b[32mOK\u001b[39m\u001b[22m\n" ] } ], "source": [ "!yes|azure login" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Credentials for Azure Python SDK" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Azure Python SDK which Simple Azure is based on requires the credential information below for ARM and ASM (Azure Service Management).\n", "\n", "- subscription ID\n", "- tenant ID\n", "- client ID\n", "- client secret\n", "\n", "The following sections demonstrate Azure CLI commands to obtain these information step-by-step." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Subscription ID and Tenant ID" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``account show`` displays subscription id and tenant id as **ID** and **Tenant ID**." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32minfo\u001b[39m: Executing command \u001b[1maccount show\u001b[22m\r\n", "\u001b[90mdata\u001b[39m: Name : Simple-Azure-Subscription\r\n", "\u001b[90mdata\u001b[39m: ID : 5s3ag2s5-2aa1-4828-xxxx-9g8sw72w5w5g\r\n", "\u001b[90mdata\u001b[39m: State : Enabled\r\n", "\u001b[90mdata\u001b[39m: Tenant ID : 5e39a20e-c55a-53de-xxxx-2503a55et6ta\r\n", "\u001b[90mdata\u001b[39m: Is Default : true\r\n", "\u001b[90mdata\u001b[39m: Environment : AzureCloud\r\n", "\u001b[90mdata\u001b[39m: Has Certificate : No\r\n", "\u001b[90mdata\u001b[39m: Has Access Token : Yes\r\n", "\u001b[90mdata\u001b[39m: User name : hroe.lee@gmail.com\r\n", "\u001b[90mdata\u001b[39m: \r\n", "\u001b[32minfo\u001b[39m: \u001b[1maccount show\u001b[22m command \u001b[1m\u001b[32mOK\u001b[39m\u001b[22m\r\n" ] } ], "source": [ "!azure account show" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "IPython filters the subscription ID and tenant ID using ``awk`` command and stores into **sid** and **tid** variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sid_tid = !azure account show|awk -F ':' '/ID/{ print $3}'\n", "sid = sid_tid[0]\n", "tid = sid_tid[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Service Principal for Simple Azure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you loaded your azure credential, a service principal is required to get access of resource groups therefore Azure Services via Azure Resource Manager and Templates are permitted to use in Simple Azure. Azure CLI provides a few commands to complete this step." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"azure ad sp create\" command create a new service principal in Active Directory with a name (--name option)." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32minfo\u001b[39m: Executing command \u001b[1mad sp create\u001b[22m\n", "+\n", "+\n", "\u001b[90mdata\u001b[39m: Object Id: 5d79f365-26e0-4993-8fe7-7021b3fd373d\n", "\u001b[90mdata\u001b[39m: Display Name: simpleazure\n", "\u001b[90mdata\u001b[39m: Service Principal Names:\n", "\u001b[90mdata\u001b[39m: ca66450a-2532-4e8b-81b2-31722d36d808\n", "\u001b[90mdata\u001b[39m: http://simpleazure\n", "\u001b[32minfo\u001b[39m: \u001b[1mad sp create\u001b[22m command \u001b[1m\u001b[32mOK\u001b[39m\u001b[22m\n" ] } ], "source": [ "out=!azure ad sp create --name simpleazure\n", "cid = out[6].split(\":\")[1].lstrip()\n", "newout=\"\\n\".join(out)\n", "print(newout)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``Id`` after Service Principal Names is our **client id** for Simple Azure. ``cid`` variable stores the ID in the previous commands." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Set a Password for Service Principal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A password for Service Principal will be used as **client_secret** later in Simple Azure.\n", "Please provide your desired password in below." ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "collapsed": true }, "outputs": [], "source": [ "password=\"\"" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32minfo\u001b[39m: Executing command \u001b[1mad sp set\u001b[22m\n", "+\n", "\u001b[90mdata\u001b[39m: Object Id: 5d79f365-26e0-4993-8fe7-7021b3fd373d\n", "\u001b[90mdata\u001b[39m: Display Name: simpleazure\n", "\u001b[90mdata\u001b[39m: Service Principal Names:\n", "\u001b[90mdata\u001b[39m: http://simpleazure\n", "\u001b[90mdata\u001b[39m: ca66450a-2532-4e8b-81b2-31722d36d808\n", "\u001b[32minfo\u001b[39m: \u001b[1mad sp set\u001b[22m command \u001b[1m\u001b[32mOK\u001b[39m\u001b[22m\n" ] } ], "source": [ "!azure ad sp set -p $password $cid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that '$cid' is a client id obtained from the previous command." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Assign Role to Service Principal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Assigning role permits certain actions to your service principal under your subscription id. \"Owner\" allows you have every rights to use resources without restrictions. See more roles: [here](https://azure.microsoft.com/en-us/documentation/articles/role-based-access-built-in-roles/)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32minfo\u001b[39m: Executing command \u001b[1mrole assignment create\u001b[22m\n", "+\n", "\u001b[36m\\\u001b[39m\u001b[90mdata\u001b[39m: RoleAssignmentId : /subscriptions/5s3ag2s5-2aa1-4828-xxxx-9g8sw72w5w5g/providers/Microsoft.Authorization/roleAssignments/6a51ba07-5470-4e09-875c-0d0362e46901\n", "\u001b[90mdata\u001b[39m: RoleDefinitionName : Owner\n", "\u001b[90mdata\u001b[39m: RoleDefinitionId : 8e3af657-a8ff-443c-a75c-2fe8c4bcb635\n", "\u001b[90mdata\u001b[39m: Scope : /subscriptions/5s3ag2s5-2aa1-4828-xxxx-9g8sw72w5w5g\n", "\u001b[90mdata\u001b[39m: Display Name : simpleazure\n", "\u001b[90mdata\u001b[39m: SignInName : undefined\n", "\u001b[90mdata\u001b[39m: ObjectId : 5d79f365-26e0-4993-8fe7-7021b3fd373d\n", "\u001b[90mdata\u001b[39m: ObjectType : ServicePrincipal\n", "\u001b[90mdata\u001b[39m: \n", "+\n", "\u001b[32minfo\u001b[39m: \u001b[1mrole assignment create\u001b[22m command \u001b[1m\u001b[32mOK\u001b[39m\u001b[22m\n" ] } ], "source": [ "!azure role assignment create --objectId $cid -o Owner -c /subscriptions/$sid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Are you completed all steps without any issues?\n", "Congraturations! You just completed login setup for your azure account." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sample Run Simple Azure after Login Setup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try to deploy a sample template using Simple Azure and the credentials that we just obtained." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import Simple Azure" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from simpleazure import SimpleAzure as saz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Credentials via Environment Variables" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import os\n", "os.environ['AZURE_SUBSCRIPTION_ID'] = $sid\n", "os.environ['AZURE_CLIENT_SECRET'] = $password\n", "os.environ['AZURE_TENANT_ID'] = $tid\n", "os.environ['AZURE_CLIENT_ID'] = $cid" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [], "source": [ "saz_obj = saz()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Template from Azure-Samples" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [], "source": [ "url = \"https://raw.githubusercontent.com/Azure-Samples/resource-manager-python-template-deployment/master/templates/template.json\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Deploy with Template and Parameters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The sample template requires three parameters:\n", "\n", "- **sshKeyData** which is ssh public key string\n", "- **dnsLabelPrefix** which is unique DNS Name for the Storage Account \n", "- **vmName** which is virtual machine name to deploy" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "saz_obj.arm.deploy(template = url, param = {\"sshKeyData\": \"ssh-rsa AAAAB3...... hroe.lee@simpleazure\", 'dnsLabelPrefix':\"simpleazure\", 'vmName':'simpleazure-first-vm'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Termination (deleting resource group)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Deleting a resource group where deployments are made stops all services and deletes resources in the group.\n", "Simple Azure uses prefixed group name 'saz' and the following function will delete the group." ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "saz_obj.arm.remove_resource_group()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" } }, "nbformat": 4, "nbformat_minor": 1 }