2

I want to run aws cli commands from lambda

I have a Pull request event that triggers when the approval state changes and whenever it's changed I need to run an aws CLI command from lambda but the lambda function says aws not found! how do I get the status on PR's in my lambda function?

7
  • 1
    Why do you want to run the AWS CLI? (It's a bit like asking whether you can ride a bicycle inside a car.) What are you wanting to achieve from the Lambda function? Commented Nov 2, 2021 at 20:50
  • I want to get an event every time when there is an ApprovalPullRequestStateChange and then run CLI commands to check if the all approval state is satisfied, if yes then I want to Merge the Pull request Commented Nov 3, 2021 at 3:53
  • AWS Lambda functions can be written in various programming languages and they can use an AWS SDK to call AWS APIs. In fact, the AWS CLI is simply a Python program that uses an AWS SDK to call AWS. You would have much more control calling AWS via a programming language, rather than trying to 'call out' to the AWS CLI. Commented Nov 3, 2021 at 4:21
  • Through AWS-SDK can I get the PR Approval Status? Commented Nov 3, 2021 at 4:36
  • Yes. Anything you can do through the AWS CLI you can do through an AWS SDK... because the AWS CLI uses the AWS SDK. Just pick an SDK for your preferred programming language and look at the documentation. There are commands that exactly match those used by the AWS CLI. By "PR Approval Status", are you referring to AWS CodeCommit? You did not mention a particular service in your question. Which AWS CLI command would you use, and what is your preferred programming language? I can point you to the appropriate documentation. Commented Nov 3, 2021 at 5:16

2 Answers 2

4

Create a lambda function, build an image to ecr, have the lambda function reference the image, and then test the image with an event. This is a good way to run things like aws s3 sync.

Testing local:

docker run -p 9000:8080 repo/lambda:latest
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

app.py

import subprocess
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def run_command(command):
    try:
        logger.info('Running shell command: "{}"'.format(command))
        result = subprocess.run(command, stdout=subprocess.PIPE, shell=True)
        logger.info(
            "Command output:\n---\n{}\n---".format(result.stdout.decode("UTF-8"))
        )
    except Exception as e:
        logger.error("Exception: {}".format(e))
        return False

    return True


def handler(event, context):
    run_command('aws s3 ls')

Dockerfile (awscliv2, can make requirements file if needed)

FROM public.ecr.aws/lambda/python:3.9

RUN yum -y install unzip

RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.0.30.zip" -o "awscliv2.zip" && \
  unzip awscliv2.zip && \
  ./aws/install

COPY app.py ${LAMBDA_TASK_ROOT}

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

CMD [ "app.handler" ]

Makefile (make all - login,build,tag,push to ecr repo)

ROOT:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
IMAGE_NAME:=repo/lambda

ECR_TAG:="latest"
AWS_REGION:="us-east-1"
AWS_ACCOUNT_ID:="xxxxxxxxx"
REGISTRY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE_NAME}
REGISTRY_URI_WITH_TAG=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE_NAME}:${ECR_TAG}

# Login to AWS ECR registry (must have docker running)
login:
    aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${REGISTRY_URI}

build:
    docker build --no-cache -t ${IMAGE_NAME}:${ECR_TAG} .

# Tag docker image
tag:
    docker tag ${IMAGE_NAME}:${ECR_TAG} ${REGISTRY_URI_WITH_TAG}

# Push to ECR registry
push:
    docker push ${REGISTRY_URI_WITH_TAG}

# Pull version from ECR registry
pull:
    docker pull ${REGISTRY_URI_WITH_TAG}

# Build docker image and push to AWS ECR registry
all: login build tag push
Sign up to request clarification or add additional context in comments.

Comments

1

The default lambda environment doesn't provide the awscli. In fact, the idea of using it there is quite awkward. You can call any command the aws cli can via an sdk like boto3 for example, which is provided in that environment.

You can however include binaries in your lambda, if you please, then execute them.

You also consider using a container image for your lambda. You can find information here: https://docs.aws.amazon.com/lambda/latest/dg/images-create.html.

4 Comments

can you help me with how can we include binaries in lambda?
@ShashankS What 'binaries' would you want to call?
cli binaries, how can I Include it in lambda function?
You just include them in the distribution. I can't remember the folder structure in the default lambda image, but you can use the runtime to get cwd to find out. Keep in mind that running binaries other than the runtime in lambda is rarely the right or best thing to do, but if you must, you'll need it to be statically linked when you compile it to ensure it has any lib links it needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.