2

Trying to run a Lambda function to invoke SSM and define an EC2 tag to push the same on multiple instances with the below script. Getting the below error when trying to execute. I am just started learning to write a script and using aws lambda first time. Please help me to fix.

import boto3
ssm = boto3.client('ssm')
ec2 = boto3.resource('ec2')

def lambda_handler(event, context):
    filters = (
        Name = 'tag:Product',
        Values = ['Essay']
    )
instances = ('filters')
response = ssm.send_command(
    InstanceIds=instances,
    DocumentName='xxxxxxxxxxxxx',
    DocumentVersion='$DEFAULT',
    DocumentHash='916fdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdcdbe7940',
    DocumentHashType='Sha256'
    )
print(response)

Error :

Response:
{
  "errorMessage": "Syntax error in module 'lambda_function': invalid syntax (lambda_function.py, line 7)",
  "errorType": "Runtime.UserCodeSyntaxError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\" Line 7\n            Name = 'tag:Product',\n"
  ]
}

Request ID:
"8cb4cd39-b744-41da-befb-5f60b6e49fa4"

Function logs:
START RequestId: 8cb4cd39-b744-41da-befb-5f60b6e49fa4 Version: $LATEST
[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module 'lambda_function': invalid syntax (lambda_function.py, line 7)
Traceback (most recent call last):
  File "/var/task/lambda_function.py" Line 7
            Name = 'tag:Product',END RequestId: 8cb4cd39-b744-41da-befb-5f60b6e49fa4
REPORT RequestId: 8cb4cd39-b744-41da-befb-5f60b6e49fa4
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Kumar
  • 33
  • 5

1 Answers1

2

There are several issues:

Wrong indentation.

There is no such thing in python as

    filters = (
        Name = 'tag:Product',
        Values = ['Essay']
    )

maybe you meant dictionary?:

    filters = {
        'Name':'tag:Product',
        'Values': ['Essay']
    }

InstanceIds=instances should be a list of strings, not a literal string of 'filters'.

The closes to fixing the code is the following:

import boto3

ssm = boto3.client('ssm')
ec2 = boto3.resource('ec2')

def lambda_handler(event, context):
    filters = [{
        'Name':'tag:Product',
        'Values': ['Essay']
    }]
    instances = [instance.id for instance in ec2.instances.filter(Filters = filters)]
    
    response = ssm.send_command(
        InstanceIds=instances,
        DocumentName='xxxxxxxxxxxxx',
        DocumentVersion='$DEFAULT',
        DocumentHash='916fdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdcdbe7940',
        DocumentHashType='Sha256'
        )
    print(response)

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 1
    I suspect the `filters` are meant to be used to identify EC2 instances upon which to run the command. Therefore, it will probably need a call to `describe_instances(Filter=...)` to obtain the list of instances, which can then be passed to `send_command()`. – John Rotenstein Sep 24 '20 at 08:45
  • @JohnRotenstein Yes, that would make most sense. – Marcin Sep 24 '20 at 08:54
  • `filters` should indeed be a dictionary. This is mainly an issue because of the confusing mix of keyword args and dictionaries that plague the AWS documentation. – Exelian Sep 24 '20 at 09:02
  • 1
    I have updated Marcin's code to retrieve a list of instances with the given tag. (Please test it before use -- I have not done so.) – John Rotenstein Sep 24 '20 at 09:13