Skip to content

chrisred/az-automation-gui-example

Repository files navigation

Azure Automation GUI

A Web App front end for Azure Automation Runbooks. Use this project as a starting point for developing custom interfaces to trigger automation tasks. Based on the Azure Static Web Apps (SWA) Free plan.

Automation GUI

Creation

Steps to create the example application.

Resource Deployment

  1. Fork this repository in Github. It can be made private if wanted.

  2. Create a Resource Group in Azure as a target for the ARM template deployment. These steps use a group named automation-gui-example.

  3. Assign a Managed Identity permissions to create an App Registration with the following steps. This is used by the ARM template during deployment.

    1. Open a PowerShell Cloud Shell session and run the commands below to create the Managed Identity in the Resource Group.
    $ResourceGroup = Get-AzResourceGroup -Name 'automation-gui-example'
    $Identity = New-AzUserAssignedIdentity -Name 'automation-gui-deploy-identity' -ResourceGroupName 'automation-gui-example' -Location $ResourceGroup.Location

    Note If the error "The subscription is not registered to use namespace 'Microsoft.ManagedIdentity'" is raised the "Microsoft.ManagedIdentity" provider will need to be registered under Subscriptions > Resource providers.

    1. Wait for the identity to appear in the portal (click refresh to check), then run the commands below in the same Cloud Shell session. There should be no errors raised.
    Connect-AzureAD
    $ManagedSp = Get-AzADServicePrincipal -Filter "displayName eq '$($Identity.Name)'"
    $GraphSp = Get-AzADServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
    
    $Permissions = @('Application.ReadWrite.OwnedBy', 'Directory.Read.All')
    $AppRoles = $GraphSp.AppRole | ?{($_.Value -in $Permissions) -and ($_.AllowedMemberType -contains 'Application')}
    $AppRoles | %{New-AzureAdServiceAppRoleAssignment -ObjectId $ManagedSp.Id -PrincipalId $ManagedSp.Id -ResourceId $GraphSp.Id -Id $_.Id}
  4. Click the deploy to Azure button to start a Custom Deployment in Azure. The Resource Group created previously should be the target of the deployment.

    Deploy to Azure

  5. Once the resources are deployed successfully follow the steps to deploy the app with Github Actions.

Template Parameters

Default values are assigned for most of the template parameters. The default values can be changed if wanted; except that the "Deployment Script Identity Name" must match the name given to the New-AzUserAssignedIdentity command in step 3, and the "Automation Webhook Expiry Time" must be an expression that sets a date in the future (1 year using the default).

App Deployment

  1. In Azure navigate to the Static Web App resource, click on "Manage Deployment Token" and copy it.
  2. In Github access the settings of the forked repository, navigate to Secrets and Variables > Actions. Create a new Repository Secret named AZURE_STATIC_WEB_APPS_API_TOKEN and set the value to the token copied in step 1.
  3. Still in Github click on staticwebapp.config.json in the root of the repository and use the "Edit this file" option to open the editor.
  4. The allowedRoles property is an empty array. Add either anonymous or authenticated to the array, authenticated will enable Azure AD authentication, anonymous allows unauthenticated access. For example: "allowedRoles": ["anonymous"]. See the section on Invitations for restricting access to approved users only.
  5. Click "Commit changes..", use the "Commit directly to the master branch" option. Github appears to treat this commit as a push, so it should trigger the Action to build and deploy the Static Web App.
  6. After the Action has completed the visit the site at the unique domain name Azure assigns. This can be found in the Static Web App resource overview.

Note When authentication is used the Static Web App resource will request consent to access basic AAD account details, the data can be removed with this process.

Hybrid Runbook Setup

Hybrid jobs can run on an Azure VM, or on an externally hosted server when it is connected using Azure Arc. This is one method to access services or data not managed by Azure.

The example creates a local Windows user account and syncs the local group names to an Azure Table so the "User Groups" drop-down list component can be populated. A Windows based Hybrid Worker is required to execute the jobs.

  1. If using an external server follow the instructions to add a server to Azure Arc. This can be skipped for Azure hosted VMs.
  2. Configure the server as a Hybrid Worker by adding it to a Hybrid Worker group. A group named automation-gui-example-[suffix] is already present in the Automation Account.
  3. Start the Runbook named automation-gui-example-sync. Provide the name of the Resource Group and the Storage Account as parameters, and run it on the Hybrid Worker. Check the job status to ensure it ran successfully.
  4. Refresh the site to pickup the change, now the "Hybrid Runbook" option on the site can be used and should create a local user.

Re-deploying the ARM Template

The following steps will remove the resources and allow the template to be re-deployed.

  1. Remove the Hybrid Worker from the group if one was used, this will make sure the extension is uninstalled correctly.
  2. Delete all the resources except for the Managed Identity (automation-gui-deploy-identity).
  3. Remove the Reader and Reader and Data Access role assignments under "Access control" on the Resource Group.
  4. Delete the App Registration.
  5. The template can now be deployed to the same Resource Group again.

Roles and Invitations

With the Free plan authenticated access is managed by Roles and Invitations. For example, in staticwebapp.config.json configure the allowedRoles property with a custom role as follows:

"allowedRoles": ["invited"]

Now for a user to access the site they must first be provided an invitation link that assigns the "invited" role.

Development

Steps to setup a basic development environment on Linux (tested with Fedora). Vue.js and Vuetify are used to build the SWA, the Azure Functions API uses Python.

Windows is not covered here, however after the prerequisites are installed the setup should be similar.

Prerequisites

Node.js, npm, Python 3.9 and Podman (or Docker) are required. For example:

sudo dnf install npm python3.9 podman

Setup

  1. Make a local clone (git clone) of the forked repository created in the deployment steps.

  2. cd to the az-automation-gui-example directory.

  3. Run npm install to install the Node.js package dependencies.

  4. Run python3.9 -m venv api/.venv to create a Python virtual environment (venv) for the Azure Functions API.

  5. Activate the venv with source api/.venv/bin/activate.

  6. Run pip install -r api/requirements.txt to install the Python package dependencies.

  7. Use the container option to run the Azurite storage emulator, and set a folder with -v to save the Azurite data into. For example:

    podman pull mcr.microsoft.com/azure-storage/azurite
    podman run -p 10000:10000 -p 10001:10001 -p 10002:10002 -v /my/data/path/here:/data:z mcr.microsoft.com/azure-storage/azurite

    The :z suffix in the volume path correctly labels the mount point when using SELinux and avoids permission errors.

  8. Create a development config for the Azure Function API at api/local.settings.json. The file should include the following contents, with any empty/example values replaced. For reference, the live version of these settings are stored by the Static Web App at Configuration > Application Settings.

    {
      "IsEncrypted": false,
      "Values": {
        "FUNCTIONS_WORKER_RUNTIME": "python",
        "AZURE_SUBSCRIPTION_ID": "",
        "AZURE_TENANT_ID": "",
        "AZURE_CLIENT_ID": "",
        "AZURE_CLIENT_SECRET": "",
        "AUTOMATION_GROUP_NAME": "my-resource-group-name",
        "AUTOMATION_ACCOUNT_NAME": "my-automation-account-name",
        "WEBHOOK_RUNBOOK": "https://my-webhook-url.example.com",
        "WEBHOOK_HYBRID": "https://my-webhook-url.example.com",
        "STORAGE_CONNECTION_STRING": "UseDevelopmentStorage=true"
      }
    }

Testing

The SWA CLI tool is used to emulate the Static Web App locally. This automatically uses the Azure Functions Core Tools to emulate Functions.

  • npx swa start http://localhost:5173 --run "npm run dev" --api-location api runs the SWA directly from the Vite development server (Vite uses port 5173 by default). Use this to get the Vue.js hot reload feature to work.
  • npx swa build az-automation-gui builds/bundles all the source files.
  • npx swa start ./dist --api-location api starts the SWA emulator using the bundled files in ./dist.
  • Ensure the Python "venv" is active when running the emulator so the correct python version and packages are available.

With either method the emulated SWA site will be available at http://localhost:4280.

Test Data

Azure Storage Explorer can connect to an emulated storage account. There a "Local storage emulator" option when adding an account. The well-known storage account and key are used to authenticate.

Using Storage Explorer any test data required can be populated.

About

Build a custom interface to Azure Automation Runbooks.

Resources

License

Stars

Watchers

Forks

Releases

No releases published