Self Service Automation with Jira Cloud & AWS

aws
jira
atlassian
Michael Dujmovitsmichael_dujmovits.jpg

Michael Dujmovits

10 minutes read

At ByteSource we ♥ automated processes for self-service capabilities. In this blog, we want to show you some details about how we automate technical aspects of our onboarding of employees and customers to our IAM (Okta) solution.

So what is the goal of self-service automation at ByteSource? In our case it helps to automate specific processes like onboarding employees, creating their accounts, give permissions down to other systems or resetting user passwords and make it as easy as possible. Okta Identity Cloud serves us as a central database to provision resources for specific customers via groups and to give users access rights to these resources and environments. In combination with Jira Service Management we can build a secure way to request these resources (users, groups, permissions) and have a proper process behind it, where requests have to be approved by specific users before they get provisioned automatically and the whole process will be audited.

Architecture

The following diagram represents all the components involved for setting up the Self-Service tool. As seen in the diagram, the whole infrastructure in AWS is built using serverless technologies to keep the maintenance effort and costs as low as possible.

self_service_jira_aws_architecture.png

Workflow

Let me explain the architecture and process using an example. A new employee was hired and he needs an account and access to our internal services.

  • To initiate the process we raise a request in our Jira Service Management Portal.
  • After the request has been approved, Jira Automation will trigger a webhook to our Lambda “Jira/Okta Automation”, using our docker container from the Elastic Container Registry, the Lambda is secured by an API Gateway and an API Key. This safety measure serves as 1st layer of defense, to prevent misuse from the outside, which is needed because the Lambda endpoint has to be public available.
  • The same Lambda will fetch all requests, which meet the requirements for being processed, from Jira Service Management. This way the lambda is also safe from any unwanted requests and can’t be exploited because it will only process requests which are coming from Jira Service Management directly from the API. There are no parameters for the Lambda, which would offer possibilities for exploits or misuse. This serves as 2nd layer of defense.
  • It will handle the new employee request and create the resource in Okta via the API.
  • The credentials to authenticate to Okta, (clientId and privateKey) and Jira Service Management (username and API token) can be securely stored in AWS Secrets Manager and are directly integrated with the AWS Secrets Manager API in the Lambda function code. This helps us to keep these credentials safe from anyone who doesn’t have the permissions to see them.
  • After creating the user in Okta, this Lambda function will post a comment with the new username and temporary password into the Jira ticket and closes it automatically.
  • All logs of Lambda are pushed to CloudWatch, which is configured to scan for errors and use Amazon EventBridge to trigger an SNS Event. SNS is used to execute another Lambda (named “Slack” in the diagram) to send a message into a dedicated Slack Channel. This way we instantly get notified if anything goes wrong.

Now our request has been closed and the user has been created, what happens next? Another Jira Automation will trigger the Lambda “Provisioning” which is responsible for executing Elastic Container Service Tasks. And these tasks will run Atlantis (Terraform Pull Request Automation) to configure and provision our internal services. You can find more details on how to use Atlantis in another blog post.

Code Examples

Let's have a deeper look into the code of the Lambda function “Jira/Okta Automation” and how we can get all open requests from Jira Service Management. We just have to provide the id from the Jira Project and credentials of a dedicated technical user:

response = requests.request(
    "GET",
    "%s/rest/servicedeskapi/request?serviceDeskId=%s&requestStatus=OPEN_REQUESTS&start=%s&limit=%s" % (
        self.url, service_desk_id, start, limit),
    headers={
        "Accept": "application/json"
    },
    auth=self.auth
)

return response.json()

After we have retrieved the open tickets from Jira Service Management, the processing of each ticket starts. And the following code would be responsible for creating a user in Okta. The Okta client is configured with oAuth2 authentication. Furthermore, we also want to generate a random temporary password, which has to be changed after the first login of the new user:

config = {
    'orgUrl': conf.okta_client_org_url,
    'authorizationMode': 'PrivateKey',
    'clientId': conf.okta_client_id,
    'scopes': ['okta.users.manage', 'okta.groups.manage'],
    'privateKey': conf.okta_private_key
}
client = OktaClient(config)

temp_password = generate_random_password()

u, resp, err = await client.create_user({
    "profile": {
        "firstName": user.first_name,
        "lastName": user.last_name,
        "email": user.email,
        "login": user.username,
    },
    "credentials": {
        "password": {
            "value": temp_password,
        }
    },
}, {
    "nextLogin": "changePassword",
    "activate": True,
})

That’s it, so now we have built a Self-Service Portal using Jira Service Management & AWS Cloud Services, which is easily extensible, scaleable, secure, has low costs and low maintenance. And it will provision everything you want automatically according to your needs.

Learn more about our Cloud Services

Cookies help us deliver our services. By using our services, you agree to our use of cookies.