In this demo, we show how to create Atlassian Jira issues and tasks based on cost recommendations in Vantage. We’ll create a script using the Vantage and Jira APIs to automate the process of retrieving financial, optimization, and waste reduction recommendations for connected cloud provider accounts. We’ll then create Jira tasks that teams can easily access and address. Organizations that use Jira as their main issue-tracking system can use this script to benefit from automated, centralized management of cost-saving opportunities for their teams.
The Scenario: Create Jira Issues for Teams Based on Vantage Recommendations
Your organization uses Jira to track issues and create tasks for development teams. You also use Vantage to manage your cloud costs. Vantage monitors your connected providers and shows cost recommendations as your infrastructure evolves and changes. You can implement these recommendations to lower your bill. An example Vantage recommendation might look like:
We found $319.00 in on demand spend last month. You can contact your Datadog account manager to commit to guaranteed spend and save around 20%.
You want to create Jira issues based on these recommendations so that the teams responsible for affected accounts or cost resources can work to implement these recommendations.
As illustrated in the workflow below, we’ll create a Python script that performs the following actions:
- Retrieves any Vantage cost recommendations based on specific input providers (AWS and Datadog for this demo)
- Creates a Jira issue for each recommendation Vantage generates within a designated timeframe
- Assigns the AWS recommendations to your Data (
DAT
) team Jira project and Datadog recommendations to your Cloud Infra (CI
) team Jira project
Prerequisites: Jira and Vantage
This demo assumes you have a basic understanding of Python, including creating functions and using loops. You should also have general knowledge of how to use Jira and create tasks. You’ll need permission to create a personal access token for Jira and permission to create tasks via the API. See the Jira documentation for information on user permissions.
Jira Permissions and Authentication
The Atlassian developer docs note, “Scripts and other REST API clients use basic authentication. Basic authentication uses an API token to authenticate the client.” See the Basic Auth Jira docs for information on how to generate an API token from your Atlassian account. The instructions will also walk you through how to base64-encode your token and email address in the form of useremail:api_token
. You’ll use this base64-encoded token in the script.
Vantage Permissions and Authentication
For Vantage, you’ll need an active account and at least one of the following provider integrations: AWS, Azure, Datadog, or Kubernetes. You’ll also need a Vantage API token with at least the READ
scope enabled.
Automate Jira Issues
All demo files are also included in the FinOps as Code demo repo.
Follow the steps below to automate converting Vantage recommendations to Jira issues for relevant teams.
Step 1: Understand the Vantage /recommendations
Endpoint Structure
To begin, we’ll send the below API request to better understand what’s returned when calling the Vantage /recommendations
endpoint.
curl --request GET \
--url https://api.vantage.sh/v2/recommendations \
--header 'accept: application/json' \
--header 'authorization: Bearer <VANTAGE_API_TOKEN>'
A successful 200
response includes a set of recommendations, similar to the below response:
"recommendations": [
{
"token": "rcmmndtn_9abc1234567efg",
"category": "ec2_rightsizing_recommender",
"workspace_token": "wrkspc_123456789123",
"provider": "aws",
"provider_account_id": "123456789123",
"description": "AWS has identified 1 EC2 instance for rightsizing that offer savings.",
"potential_savings": "397.4661552657",
"service": "AWS EC2",
"created_at": "2024-01-09T09:49:12Z",
"resources_affected_count": 1
},
]
Note that a summary of the recommendation and potential savings are provided, which can be used in the Jira issue’s title and description.
In the GET
call, you can also pre-filter the response with the following query parameters:
workspace_token
(See the Vantage docs for more information)provider
(e.g.,aws
)provider_account_id
(e.g., AWS account number, Azure subscription ID)category
(e.g.,savings_plan
; see the API docs for a full list of options)
In this scenario, we’ll use the provider
query parameter so that we can filter for aws
and datadog
recommendations and send them to the DAT
and CI
Jira projects respectively.
Step 2: Declare Imports and Credential Variables
Export your Vantage API access token and base64-encoded Jira token as environment variables.
export VANTAGE_API_TOKEN=<YOUR_VANTAGE_API_TOKEN>
export JIRA_TOKEN=<BASE64_ENCODED_EMAIL_TOKEN>
Create a Python script and add the following package imports:
import requests
import json
from datetime import datetime, timedelta
import os
# Jira information
# Add your Jira URL, which might differ from the below format
jira_url = "https://<YOUR_ORG>.atlassian.net/"
issue_type = "Task"
# Vantage information
vantage_headers = {
"accept": "application/json",
"authorization": f"Bearer {os.environ.get('VANTAGE_API_TOKEN')}"
}
- Use
requests
to connect with the Vantage and Jira APIs. - Use
json
to parse the API requests and responses. - Use
datetime
to access the current date. - Use
os
to access environment variables.
Add in the required Vantage and Jira variables.
Step 3: Create a Function to Generate Jira Issues
Next, we’ll create a map of providers and matching Jira project IDs.
# Map of providers and corresponding Jira project IDs
providers_projects = {
"aws": "DAT",
"datadog": "CI"
}
Then, declare a function that creates a Jira issue for each Vantage recommendation.
# Create a Jira issue
def create_jira_issue(project_key, summary, description):
url = f"{jira_url}/rest/api/2/issue"
headers = {"Content-Type": "application/json", "Authorization": f"Basic {os.environ.get('JIRA_TOKEN')}"}
payload = {
"fields": {
"project": {"key": project_key},
"summary": summary,
"description": description,
"issuetype": {"name": issue_type}
}
}
response = requests.post(
url,
data=json.dumps(payload),
headers=headers
)
if response.status_code == 201:
print("Issue created successfully.")
issue_key = response.json().get("key")
print(f"Issue key: {issue_key}")
else:
print(f"Failed to create issue. Status code: {response.status_code}")
print(response.json())
This function should:
- Create an issue via the Jira API
- Pull in the
jira_url
andheaders
that were previously defined - Take in the project key from the
providers_projects
map, as well as thesummary
anddescription
that will come from the Vantage API’s response (done in next step) as part of thepayload
- Return confirmation of success or failure for each call
Step 4: Create a Function to Fetch and Process Vantage Recommendations
Now that the Jira function is set up, create a function that fetches data from the Vantage API.
# Fetch recs from Vantage and create a Jira issue
def process_recommendations(provider, project_key):
vantage_url = f"https://api.vantage.sh/v2/recommendations?provider={provider}"
response = requests.get(vantage_url, headers=vantage_headers)
if response.status_code == 200:
recommendations = response.json().get("recommendations", [])
current_time = datetime.utcnow()
past_month = current_time - timedelta(days=30)
for recommendation in recommendations:
created_at = datetime.strptime(recommendation["created_at"], "%Y-%m-%dT%H:%M:%SZ")
if created_at >= past_month:
service = recommendation["service"]
description_text = recommendation["description"]
potential_savings = float(recommendation["potential_savings"])
summary = f"{service}: Vantage Cost Recommendations"
description = f"""
A cost recommendation was found for {service} in Vantage.
{description_text}
The recommendation has a potential savings of ${potential_savings:.2f}.
[View all|https://console.vantage.sh/recommendations?provider={provider}] Vantage recommendations.
"""
create_jira_issue(project_key, summary, description.strip())
else:
print(f"Failed to retrieve recommendations for {provider}. Status code: {response.status_code}")
print(response.text)
This function should:
- Take in the previously defined
vantage_url
andvantage_headers
- Calculate a
timedelta
between today and 30 days before to include only the last month of recommendations—you can adjust thistimedelta
based on your needs and how often you intend to run this script - Query the
/recommendations
endpoint of the Vantage API with a query parameter for the provider defined in theproviders_projects
map - Create a
summary
anddescription
based on the values obtained from theservice
,description
, andpotential_savings
in the Vantage API response- The
description
also contains a link back to the Vantage console for additional investigation
- The
- Invoke the
create_jira_issue
function with this data as parameters for each recommendation
Step 5: Iterate Over the providers_projects
Map
Finally, iterate over the providers_projects
map to run the script for each Jira project.
# Iterate through the providers_projects map for each project
for provider, project_key in providers_projects.items():
process_recommendations(provider, project_key)
Once complete, you should see tasks for each Jira project based on the recommendations Vantage provides, similar to the example below.
Next Steps
Congratulations—you just set up a basic automation to send Vantage recommendations to Jira as issues. You can easily adjust the timeframe for which you want to process issues, or change any of the query parameters to filter for different recommendation types. Consider using other Vantage endpoints, like the /anomaly_alerts
endpoint, to send additional data to Jira. Check out our FinOps as Code demo repository for more projects and ways you can automate your cloud cost data.
Lower your AWS costs.