Hi Raviraj,
Yes, we have checked CURL and POSTMAN with complete end point of API URL with one single Asset ID was working fine, which we did check along with Nivedha from Freshservice Support.
Here our requirement is to update all the AWS VMs Tags information automatically from AWS to Freshservice using AWS Lambda function by integrating Freshservice API URL, which is not working…
We are getting an error “Failed to fetch assets from Freshworks: 404”
===================Here is the AWS Lambda Code we used in our Sandbox Environment=========================
import boto3
import requests
from datetime import datetime
AWS Config Aggregator details
aggregator_name = ‘aws-controltower-GuardrailsComplianceAggregator’
region_name = ‘us-west-2’ # Specify your region
Freshworks API details
freshworks_domain = ‘cepheidservicedesk-sandbox-jan-23.freshservice.com/api/v2/assets/{asset_id}’
freshworks_api_key = ‘2b3xxxxxxxxxxxxxx’
AWS account ID for Freshworks
aws_account_id = ‘994000000000’
Initialize AWS Config client
config_client = boto3.client(‘config’, region_name=region_name)
Function to convert datetime objects to strings
def convert_datetime(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(“Type not serializable”)
Function to get instance details and tags from AWS Config Aggregator
def get_instance_details(aggregator_name):
try:
Check if the aggregator exists
config_client.describe_configuration_aggregators(
ConfigurationAggregatorNames=[aggregator_name]
)
Get the list of aggregated resources
paginator = config_client.get_paginator(‘list_aggregate_discovered_resources’)
page_iterator = paginator.paginate(
ConfigurationAggregatorName=aggregator_name,
ResourceType=‘AWS::EC2::Instance’
)
instance_details =
for page in page_iterator:
for resource in page[‘ResourceIdentifiers’]:
resource_details = config_client.get_aggregate_resource_config(
ConfigurationAggregatorName=aggregator_name,
ResourceIdentifier={
‘SourceAccountId’: resource[‘SourceAccountId’],
‘SourceRegion’: resource[‘SourceRegion’],
‘ResourceId’: resource[‘ResourceId’],
‘ResourceType’: resource[‘ResourceType’]
}
)
instance_details.append(resource_details[‘ConfigurationItem’])
return instance_details
except config_client.exceptions.NoSuchConfigurationAggregatorException:
print(f"The configuration aggregator ‘{aggregator_name}’ does not exist.")
return
Function to get asset IDs from Freshworks
def get_freshworks_assets():
url = f"https://{freshworks_domain}/api/v2/assets"
headers = {
‘Authorization’: f’Bearer {freshworks_api_key}',
‘Content-Type’: ‘application/json’
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()[‘assets’]
else:
print(f"Failed to fetch assets from Freshworks: {response.status_code}")
return
Function to update tags in Freshworks
def update_freshworks_tags(asset_id, tags):
url = f"https://{freshworks_domain}/api/v2/assets/{asset_id}"
headers = {
‘Authorization’: f’Bearer {freshworks_api_key}',
‘Content-Type’: ‘application/json’
}
payload = {
‘asset’: {
‘custom_fields’: tags
}
}
response = requests.put(url, headers=headers, json=payload)
if response.status_code == 200:
print(f"Successfully updated tags for asset ID {asset_id}")
else:
print(f"Failed to update tags for asset ID {asset_id}: {response.status_code}")
Define the required tag keys
required_tag_keys = [
“AccountName”, “Environment”, “Application”, “BusinessApplicationName”,
“SystemCriticality”, “PatchGroup”, “SystemName”, “RegionName”,
“ITOwner”, “ITDepartment”, “SystemOwner”, “SystemOwnerDepartment”,
“SystemFunction”, “SystemCreator”, “SystemRequester”, “CostCenter”,
“SystemType”, “Backup”
]
def lambda_handler(event, context):
Get instance details
instances = get_instance_details(aggregator_name)
Get Freshworks assets
freshworks_assets = get_freshworks_assets()
Create a mapping of instance IDs to asset IDs
asset_mapping = {asset[‘unique_identifier’]: asset[‘id’] for asset in freshworks_assets}
Process instance details and update tags in Freshworks
if instances:
for instance in instances:
instance_id = instance[“resourceId”]
account_id = instance[“accountId”]
tags = instance.get(“tags”, {})
Ensure all required tag values are present in the correct order
tag_values = {tag: tags.get(tag, “N/A”) for tag in required_tag_keys}
Update tags in Freshworks if the instance ID matches an asset ID and account ID matches
if instance_id in asset_mapping and account_id == aws_account_id:
update_freshworks_tags(asset_mapping[instance_id], tag_values)
return {
‘statusCode’: 200,
‘body’: ‘Instance tags have been updated in Freshworks.’
}
===================Here is the AWS Lambda Code we used in our Sandbox Environment=========================
Thanks and Regards
Naresh Kambam