简体   繁体   中英

create cloudwatch dashboard with boto3 using lambda

i want to create cloudwatch dashboard for multiple EC2 i have problem to put JSON dashboard bady and make region and id instance value be variable

the code

from __future__ import print_function

import json

import boto3

def lambda_handler(event, context):

    ec2_client = boto3.client('ec2')
    CW_client = boto3.client('cloudwatch', region_name='eu-west-1')

    regions = [region['RegionName']
               for region in ec2_client.describe_regions()['Regions']]
    for region in regions:
        print('Instances in EC2 Region {0}:'.format(region))
        ec2 = boto3.resource('ec2',region_name=region)

        instances = ec2.instances.filter(
            Filters=[
                {'Name': 'tag:backup', 'Values': ['true']}
            ]
        )
        for i in instances.all():
            #for ID in i.InstanceId.all():
            print(i.id)
            instance_id = i.id
            response = CW_client.put_dashboard(DashboardName='test', DashboardBody='{"widgets": [{"type": "metric", "x": 12, "y": 0, "width": 12, "height": 6, "properties": {"metrics": [[ "AWS/EC2", "CPUUtilization", "InstanceId", instance_id ]], "view": "timeSeries", "stacked": false, "region": region, "stat": "Average", "period": 60, "title": "CPUUtilization" }}]}')

the error


  "errorMessage": "An error occurred (InvalidParameterInput) when calling the PutDashboard operation: The field DashboardBody must be a valid JSON object",
  "errorType": "DashboardInvalidInputError",

Your DashboardBody contains the literal string instance_id and region (without quotes). That's why the JSON is invalid. You need the values of instance_id and region , not the bare words instance_id and region .

You should use string interpolation. For example:

region = "us-east-1"
instance_id = "i-1234567890"

partbody = '{"region":"%s", "instance_id":"%s"}' % (region, instance_id)

Or you could use f-strings but then you'd have to quote the braces, like so:

partbody = f'{{"region":"{region}", "instance_id":"{instance_id}"}}'

Both options result in a string that looks like this:

{"region":"us-east-1", "instance_id":"i-1234567890"}

Note that I'm showing you how to use string interpolation to inject variable values into a string. Now you need to do this and inject both region and instance_id into the DashboardBody string. For example:

DashboardBody='{"widgets": [{"type": "metric", "x": 12, "y": 0, "width": 12, "height": 6, "properties": {"metrics": [[ "AWS/EC2", "CPUUtilization", "InstanceId","%s" ]], "view": "timeSeries", "stacked": false, "region":"%s", "stat": "Average", "period": 60, "title": "CPUUtilization" }}]}' % (instance_id, region)
Your json body for 'DashboardBody' should be like this:

    {
       "widgets": [
          {
             "type": "metric",
             "x": 12,
             "y": 0,
             "width": 12,
             "height": 6,
             "properties":{
                "metrics":[
                   [
                      "AWS/EC2",
                      "CPUUtilization",
                      "InstanceId",
                      instance_id
                   ]
                ],
                "view": "timeSeries",
                "stacked": false,
                "region": regions,
                "stat": "Average", 
                "period": 60, 
                "title": "CPUUtilization"

             }
          }
       ]
    }

Also You were passing incorrect value for "region" parameter, it should be regions (as declared in your code) and not region.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM