Jira Cloud: Create MS365 Users with Automation and Azure Runbooks

I’ve created the same instructions with group membership capabilities on this page for you.

If you use Jira or Jira Service Management (JSM) for your Helpdesk or IT Support, you might want to automate your onboarding process. One essential step in onboarding is automating user creation within Microsoft 365, now called Microsoft Entra (formerly Azure AD). You can seamlessly accomplish this task with Jira’s powerful automation features and Atlassian’s recently introduced “Start an Azure Runbook” action.

But why should you consider this approach?

  • Save Time: Automate repetitive tasks, reducing manual effort and human error.
  • Improve Efficiency: Streamline onboarding processes, ensuring a smooth and timely experience for new users.
  • Enhance Security: Enforce consistent provisioning standards and minimize security risks.

Let’s explore how to set up this integration and prove why it’s a valuable addition to your Jira IT toolkit.   I apologize in advance. This guide will be on the longer side, but I promise it’s worth it. 


 

Create the Azure Automation Account

First up, we’ll set up an Azure Runbook. This will use a PowerShell script to create the new user account.

    • Search for “Automation Accounts” in the search bar.
    • Click + Create to set up a new Automation Account.
  • Provide the required details:
    • Subscription: Select your Azure subscription.
    • Resource Group: Choose or create a resource group.
    • Name: Enter a name for your Automation Account.
    • Region: Select your preferred region.
    • Click Next

  • Under Advanced, choose System Assigned under Managed Identities.  We will go over why this may be your best option later.
  • Networking tab, ensure you have public access enabled for your connectivity configuration.
  • Setup your Tags (Highly recommended for housekeeping).
  • Click Review + Create and then Create.

After your Automation Account has been created, Go to the resource.

If you're a new Automation account user and can't find the Modules option under Shared Resources, you may need to switch to the Old Experience. To do this, locate the 'Switch to Old Experience' option at the top of your Automation account.

Create Runbook

Now, to set up your new runbook.  Under the Process Automation blade, click the arrow to expand and choose Runbooks.

You can delete the two tutorial runbooks if you wish (That’s my OCD is talking).

  • Next, click + Create to create a new runbook.

Provide the needed details

  • Click Create new.
  • Enter a name for your runbook.
  • Select PowerShell as the runbook type.
  • Choose ‘Select from existing’ for the runtime environment and select PowerShell-7.2 (or the latest release). This is necessary to use the MS Graph API.
  • Add a description for your runbook.
  • Optionally, add tags to categorize your runbook.
  • Click Review + Create.
  • Once validation is complete, click Create.
  • Allow 2-3 minutes for the runbook to be created.

 

Our runbook will need specific PowerShell modules that aren’t installed by default.

To add them:

  • Click the + Add a module button at the top.

  • Click ‘Browse from the gallery.’
  • Search for ‘Microsoft.Graph.Authentication’ in the module gallery.
  • Select the latest version of the module.
  • Click
  • Choose the latest runtime version for your module.
  • Click Import.

It might take a little while to import the Microsoft.Graph.Authentication module. You can check its progress by searching for it in the module gallery. Once it says ‘Available,’ you’re ready to use it!

Continue the same steps above to add the other modules you may need:

  • Microsoft.Graph
  • Microsoft.Graph.Users
  • Microsoft.Graph.Users.Actions

You may not need all these modules. The best practice is only to add the modules you may need.

You should have a similar view:

To enable your runbook to create users, we need to grant it permissions:

  • Go to Account Settings, choose Identity.
  • You’ll see a system-assigned managed identity is already enabled.
  • Click Add role assignment.
  • Set the scope to your Azure subscription.
  • Assign the Contributor role (or create a custom role with necessary permissions which is recommended).

  • Click Save.
  • Copy the object ID of the managed identity for future reference. We’ll be using this coming up.

 

Quick Discussion: Why Use A Systems Assigned Managed Identify?

System-assigned managed identities are a powerful tool for securing and simplifying Azure Automation Runbooks. Here’s why:

  • Simplified Authentication: Managed identities eliminate the need for storing and managing sensitive credentials within your runbook.
  • Built-in Lifecycle Management: Azure automatically creates and manages the identity, ensuring it’s tied to your Automation Account and deleted when necessary.
  • Improved Security: By leveraging Azure Active Directory, managed identities provide a secure way to authenticate with Azure resources.
  • Role-Based Access Control (RBAC): You can assign specific permissions to the managed identity, minimizing the risk of unauthorized access.
  • Ease of Use in Runbooks: Acquiring access tokens within your runbook is straightforward, allowing seamless interaction with Azure resources.
  • Cost Efficiency: Managed identities are a free Azure feature, making them cost-effective.

 

Setup permission for your Object ID

We have one more step: Give our new Managed identity permissions to create users.  Ensure you have the Object ID from your Managed Identity from the steps above.

  • In a new tab, Go to the Azure portal.
  • Choose the Microsoft Entra ID blade
  • Expand Manage, choose Enterprise applications.
  • On the search bar, search for the Object ID you have copied.
  • An application should show up; click on the name.
  • Expand the Security area, choose Permissions, and you’ll notice there are no Permissions set for your application.

We need to give this application Microsoft Graph – User.ReadWrite.All permissions.  There is currently only one way to do this: through PowerShell.

The easiest way to do this is to open the Cloud Shell at the top of your Azure portal.  

Run the following PowerShell Script. Make sure you replace **SUPERCOOLOBJECTID** with the Object ID of the application you just searched for.

				
					Install-Module Microsoft.Graph -Scope CurrentUser

Connect-MgGraph -Scopes Application.Read.All, AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory

$managedIdentityId = "SUPERCOOLOBJECTID"
$roleName = "User.ReadWrite.All"

$msgraph = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$role = $Msgraph.AppRoles| Where-Object {$_.Value -eq $roleName} 

New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityId -PrincipalId $managedIdentityId -ResourceId $msgraph.Id -AppRoleId $role.Id
 
Disconnect-MgGraph
				
			

The Cloud console will run. 

Choose A for Yes to All to install all the required Graph modules.  This will run for a few minutes.

It will then prompt you to Sign into a web browser and enter a code.   Simply copy the URL (or click the URL) and type the code into your browser.

  • Enter the code to allow access. Click Next

  • The next screen will ask you to sign into your account to verify.
  • After you log in, you will need to consent on behalf of your company to give permissions to the Graph Command Line Tools. If you are okay with this, click Accept.

You can now close the tab where you granted admin consent. Return to the tab where your Azure Cloud Shell is running. The permission grant process should be complete, and your cloud shell should be disconnected from Microsoft Graph.

To verify that the permissions have been added successfully:

  • Navigate back to the Permissions tab of your enterprise application.
  • You should now see the User.ReadWrite.All permission listed, with admin consent granted.

Let’s go back to our runbook that we created.  Click the runbook and make sure you’re in the runbooks Overview view.

To edit your runbook:

  • Navigate to our runbook in the Azure portal.
  • Click ‘+ Edit’ and choose Edit in the portal.
  • Expand the Runbooks section on the left and select the correct runbook.
  • We’re ready to add our PowerShell script.
				
					param (
    [Parameter(Mandatory=$true)]
    [string]$FirstName,
    
    [Parameter(Mandatory=$true)]
    [string]$LastName,
    
    [Parameter(Mandatory=$true)]
    [string]$InitialPassword,
    
    [Parameter(Mandatory=$false)]  #Note we're not making this field mandatory.
    [string]$Department = $null,
    
    [Parameter(Mandatory=$false)]
    [string]$JobTitle = $null
)

# Import required modules. You should have already installed these on the runbook.
Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Users

# Initialize output object
$OutputObject = @{
    Status = $null
    UserDetails = $null
    ErrorMessage = $null
    Timestamp = $null
}

try {
    # Connect using Managed Identity
    Connect-MgGraph -Identity

    # Construct email address
    $FirstNameLower = $FirstName.ToLower()
    $LastNameLower = $LastName.ToLower()
    $UserPrincipalName = "$FirstNameLower.$LastNameLower@daveherrell.com" #Make sure you change the domain to your domain.
    $MailNickname = "$FirstNameLower$LastNameLower"

    # Construct display name
    $DisplayName = "$FirstName $LastName"

    # Prepare password profile
    $PasswordProfile = @{
        Password = $InitialPassword
        ForceChangePasswordNextSignIn = $true
    }

    # Prepare user parameters
    $UserParams = @{
        DisplayName = $DisplayName
        GivenName = $FirstName
        Surname = $LastName
        UserPrincipalName = $UserPrincipalName
        MailNickname = $MailNickname
        AccountEnabled = $true
        PasswordProfile = $PasswordProfile
    }

    # Add optional parameters if provided
    if ($Department) { $UserParams.Department = $Department }
    if ($JobTitle) { $UserParams.JobTitle = $JobTitle }

    # Create user
    $NewUser = New-MgUser @UserParams

    # Prepare output object
    $OutputObject.Status = "Success"
    $OutputObject.UserDetails = @{
        DisplayName = $DisplayName
        UserPrincipalName = $UserPrincipalName
        ObjectId = $NewUser.Id
        Department = $Department
        JobTitle = $JobTitle
    }
    $OutputObject.Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")

    # Output detailed results
    Write-Output "User Creation Status Report:"
    Write-Output "----------------------------"
    Write-Output "Status: $($OutputObject.Status)"
    Write-Output "Full Name: $DisplayName"
    Write-Output "Email Address: $UserPrincipalName"
    Write-Output "User Object ID: $($NewUser.Id)"
    Write-Output "Timestamp: $($OutputObject.Timestamp)"
    
    return $OutputObject
}
catch {
    # Capture error details
    $OutputObject.Status = "Failed"
    $OutputObject.ErrorMessage = $_.Exception.Message
    $OutputObject.Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")

    # Output error information
    Write-Error "User Creation Failed:"
    Write-Error "-------------------"
    Write-Error "Error Message: $($OutputObject.ErrorMessage)"
    Write-Error "Timestamp: $($OutputObject.Timestamp)"

    throw
}
				
			

NOTE: Make sure you change the domain name on line 37

  • Click Save.  Click Publish.

Before proceeding, we should test our runbook to ensure it works as expected. After all, if it doesn’t work here, the Jira automation definitely wont work.  

  • In the runbook editor, navigate to the Test pane.
  • Fill in the necessary parameters for the runbook to execute.
  • Click the Start button to initiate the test.
  • Please allow up to 3-5 minutes for the test to complete.
  • Once the test finishes, review the output to verify that it ran successfully and without errors.

 

Within the Azure Portal, expand the Microsoft Entra bade, expand Manage, and choose Users. 

There, you will find your newly created user from your test run.

Open your new user, select Properties, and verify that everything was created as expected.

House Keeping 101: If you no longer need this test account, delete it.


Setting up Jira Automation

Ok, we have set up and tested our Azure runbook.  Now, let’s move on to the easier part of setting up the Jira Automation.  But first, what’s the scenario?

Our Scenario

A new onboarding ticket is created in Jira to signal the start of a new hire's onboarding process. HR completes all necessary information about the new employee in the Onboard Information tab. Once the Employee Information Review field is set to Yes and the ticket is moved to the Create New User status, we want to automate the creation of the new user in Azure AD based on the information provided within the Jira ticket
  • Click your Project settings and go to Automation.
  • Choose Create Rule.
  • Our trigger will be when the Issue is Transitioned; select this option.
    • Our criteria are from status: In Progress to status
    • Create New User.
    • Click Next.

Let’s add a safeguard to ensure somebody has reviewed the info and set the review field to yes.

  • Add the IF: Add a condition
  • Choose Issue fields condition.
    • Under Field, we choose the Employee Information Reviewed.
    • Condition, equals
    • Value is Yes
    • Click Next.

Let’s add a branch component to work only off the issue that triggered it.  Choose FOR EACH: Add a branch, and select the Branch rule / related issues.   Choose Current Issue (default) on the next screen and click Next.

  • Click the Add to branch under your new Branch. Select the THEN: add an action. 
  • Search or scroll down to the Start runbook in Azure and choose it.
  • Next, we need to Connect our Azure account to our Jira account. Click the Connect   This will open a new window.
  • Sign in to your MS365 account if you’re not already signed in.
  • Review and approve the permissions request on behalf of your organization. Click
  • This tab should close out, taking you back to your Jira Automation.

  • Within Jira Automation, Select your Azure Subscription name
  • Select the Resource Group that has your automation account.
  • Select the Automation account that holds your runbook.
  • Lastly, select the runbook we just set up.

The last thing we need to do is bind the Key-value pairs so the payload we send to Azure has the information to give to our runbook script.

In our simple example, we’re going to map four pairs of values (attributes).

  • FirstName
  • LastName
  • Department
  • JobTitle

We’ll automate the creation of a temporary password for each new user. To simplify this tutorial, we’ll assign the same temporary password to every new user.

In the table below is how we’ll be mapping the key-value pairs:

FirstName

String

{{issue.customfield_10058}}

LastName

String

{{issue.customfield_10059}}

Department

String

{{issue.customfield_10060}}

JobTitle

String

{{issue.customfield_10061}}

InitialPassword

String

Sup3rCoolP@asword

You must insert the custom field IDs that your Onboarding tickets use.  I have a handy guide here if you need help finding the Jira custom field IDs.

 

 

Once you’ve added all your key-value pairs, select Next.

Click the Rule Details at the top.

  • Name your rule
  • Set a description. (please do this for good housekeeping).
  • Set the Automation Owner.
  • Set the Actor (typically Automation for Jira)
  • Select if you want an email if this rule errors out.
  • Who can edit the rule?
  • Lastly, click Turn on Rule.


 

Let’s Test It!

The last thing to do is test your automation and runbook!  We’ll test with the newly created HR Onboarding test ticket with the required information filled out. 

Per our requirements, the Employee Information Reviewed is already set to Yes.  The ticket transitioned from In Progress to Create New User.

 

 

If we go to our Jira Automation rule and click the Audit log, we can see the runbook request was submitted.

 

 

Back in the Azure portal, if we open our runbook, we should see our Runbook either running or completed already.

 

 

If you click the Completed Status, you will see our Inputs, Errors, etc.

 

 

Last thing, you should see your newly created user within the Entra ID User area!

 

 

We have now set up a new Azure Entra user using Jira automation!

 

After posting this write-up, I’ve been asked if Azure can write back as a comment to the Jira ticket with the status of the runbook and even the logged output parameters. While it's not feasible to write back via shortcodes using Jira Standard or Premium, Jira Enterprise offers advanced capabilities that allow real-time updates, including posting runbook status and output as comments or custom fields. However, you can update the PowerShell script utilizing Jira's API that can write back information to your tickets. This requires setting up a Jira API key and other factors too in-depth for this guide.

 

Wrap up notes:

This guide covers the basic steps to automate user provisioning in Microsoft Entra using Jira and Azure Automation Runbooks.

To further enhance this automation:

  • Expand user information: Add fields like address, phone number, manager, etc., to your PowerShell script. Consider using dynamic properties for flexibility.
  • Implement password security: Develop a password generator within your script to avoid storing plain text passwords.
  • Validate input: Add validation to ensure usernames and other parameters are valid such as username conflict.
  • Utilize MS365 Dynamic Distribution and Security Groups:  Take advantage of dynamic group membership to go along with your new account creations. Example adding them to the US-Employees distro or maybe the slack-users group so the SCIM will also create their Slack account.

Jira Automation Considerations:

  • Workflow conditions: Configure workflow conditions to restrict who can transition tickets and trigger automation.
  • Issue security: Issue security schemes control the visibility of sensitive ticket information.

 

This guide should provide a solid foundation for automating user provisioning. With further exploration and customization, you can unlock the full potential of Azure Automation and Jira to streamline your workflows and enhance security.

I hope you found this helpful!