boto3 : SSM Parameter get_parameters()

Question:

I am creating lambda function where I am fetching SSM parameter for EKS-Optimized AMI ID, now about EKS-Optimized AMI, it is the default AMI provided by EKS if we are not specifying any AMI explicitly. EKS-Optimized AMI are different per region & K8 version. I am working on upgrading this AMI on node groups & getting this AMI ID here for K8 version 1.21. I want to pass this k8 version ${EKS_VERSION} to get-parameter() as

ami_id = ssm.get_parameters(Names=["/aws/service/eks/optimized-ami/${EKS_VERSION}/amazon-linux-2/recommended/image_id"])

Can you help me if we can do this in boto3, if yes,how ?
Thanks in advance!

Asked By: buttercup

||

Answers:

Maybe I am missing the point of the question but it is pretty straightforward as you already have the request in your question. If you put the following code into your lambda, it should get you the version you want in that region.

For something like this, you may want to use a lambda env variable with a default, and overwrite it when you want something different.

    import boto3
    import ssm
    
    # get an ssm client
    ssm_client = boto3.client('ssm')
    
    # you need to pass the var somehow, here assuming you are using an environment variable in your lambda. You could use some other system to trigger and pass the information to your lambda, e.g. sns
    eks_version = os.getenv('EKS_VERSION')
    
    # set the parameter name you want to receive, note the f-string to pass the variable to it
    param_name = f"/aws/service/eks/optimized-ami/{eks_version}/amazon-linux-2/recommended/image_id"
    
    
    # get_parameter
    response = ssm_client.get_parameters(Names=[param_name])
    
    # print / return response
    print(response)

For overwriting the param, you could use sns or cloudwatch with lambda if you are building some kind of automation but you would need to parse the input from them.
For example a simple json payload in sns

{
 "eks_version": 1.21
}

and in your code, you can change make small adjustment once you parsed the sns payload. e.g.

import json
if 'Sns' in the event:
   sns_eks_version = json.loads(event['Records'][0]['Sns']['Message']['eks_version'])
else:
   sns_eks_version = None
eks_version = sns_eks_version or os.get_env('EKS_VERSION')
Answered By: Adil Hindistan

This is how I did :

import json
import os
import boto3

ssm_client = boto3.client('ssm')
eks_client = boto3.client('eks')

eksClusterName='dev-infra2-eks'

def lambda_handler(event, context):
    # Get current EKS Version
    response = eks_client.describe_cluster(
        name = eksClusterName
    )
    eksVersion = response['cluster']['version']
    
    aws_eks_ami_ssm_param = "/aws/service/eks/optimized-ami/"+eksVersion+"/amazon-linux-2/recommended/image_id"

    # Get SSM param for AMI ID
    try:
        eks_ssm_ami = ssm_client.get_parameter(Name=aws_eks_ami_ssm_param)
        latest_ami_id = eks_ssm_ami['Parameter']['Value']
        return latest_ami_id
    except client.exceptions.ParameterNotFound:
        logging.error("Parameter Not Found")
Answered By: buttercup