TIM02144
TIM02144

Reputation: 615

Lambda Python to Query SSM Parameter Store Value

I want to write a Python 3.6 query in AWS Lambda to get details on an AWS SSM parameter store but I get a null response. If I query via AWS CLI I get the details on the parameter store item including the AMI ID which is my ultimate goal. The parameter store path is:

/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-Base-2019.07.12

My code is below, any insight into why this is not returning the expected results would be greatly appreciated.

import json
import boto3

def lambda_handler(event, context):
    client = boto3.client('ssm')
    response=client.get_parameters(Names=['/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base']),
    #return "Success"
    print (response)

I'm expecting the same output that I get when I run the following AWS CLI command.

aws ssm get-parameters --names /aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base --region us-east-1

Upvotes: 14

Views: 17686

Answers (4)

Manuel Montoya
Manuel Montoya

Reputation: 1446

Although boto3 is a viable way to do this, the current recommended way is to enable the AWS Parameters and Secrets Lambda Extension. From the docs:

This extension retrieves parameter values and caches them for future use. Using the Lambda extension can reduce your costs by reducing the number of API calls to Parameter Store. Using the extension can also improve latency because retrieving a cached parameter is faster than retrieving it from Parameter Store.

Code sample:

import os
import json
import urllib.request
from urllib.parse import quote_plus

aws_session_token = os.environ.get('AWS_SESSION_TOKEN')
parameter_store_extension_url = (
    "http://localhost:2773/systemsmanager/parameters/get?name={name}&withDecryption={with_decryption}"
)


def lambda_handler(event, context):
    my_parameter = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base"
    with_decryption = True

    # Retrieve /my/parameter from Parameter Store using extension cache
    req = urllib.request.Request(
        parameter_store_extension_url.format(
            name=quote_plus(my_parameter),  # Quote the parameter name so that it is url-compatible
            with_decryption="true" if with_decryption else "false"
        ),
    )
    req.add_header("X-Aws-Parameters-Secrets-Token", aws_session_token)
    config = urllib.request.urlopen(req).read()

    return json.loads(config)

Upvotes: 1

You can use this library which has error handling out-of-the-box: AWStanding

from awstanding.parameter_store import load_parameters

LOOKUP_DICT = {
  '/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base': 'CONVENIENT_NAME'
}

load_parameters(LOOKUP_DICT)

os.environ.get('CONVENIENT_NAME')

The advantage here is that you can easily load a lot of parameters with minimmum overhead.

Upvotes: 0

TIM02144
TIM02144

Reputation: 615

I figured this out with the help of a co-worker with more Python experience. The code is below.

import boto3

client = boto3.client('ssm')

def lambda_handler(event, context):
    parameter = client.get_parameter(Name='/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base', WithDecryption=True)
    print(parameter)
    return parameter ['Parameter']['Value']

Upvotes: 24

amittn
amittn

Reputation: 2355

  • Worth checking your lambda has enough permissions to interact with aws SSM. Just for the initial checking i would suggest give full access by using policy policy/AmazonSSMFullAccess
  • Lambda IAM role should have the above policy.
  • docs aws boto3 docs

Upvotes: 1

Related Questions