Connecting to AWS CodeCommit Repositories from an AWS Lambda Function
Last updated: August 16, 2019
AWS CodeCommit offers secure Git-based repositories. To connect to CodeCommit repositories, you can use Git together with the credential helper that is part of the AWS Command Line Interface (CLI). AWS CodeCommit supports Git versions 1.7.9 and later.
To perform different operations on your CodeCommit repositories, you can also use the AWS SDK. For example, you can add or update a file in a branch, generate a commit, or get contents of a specified file using the AWS SDK.
If you want to communicate with your CodeCommit repositories from a Lambda function, you may decide to use Git instead of the AWS SDK. In this case, you have to make Git available in the execution environment of this Lambda function. You do not need to expose any CodeCommit repository credentials in your Lambda function because the AWS Lambda IAM role credentials can be used to authenticate to AWS CodeCommit.
The following procedure describes how to connect to CodeCommit repositories from a Lambda function using the command-line Git client and the IAM role credentials of this Lambda function.
How to Connect to a CodeCommit Repository from a Lambda Function Using the IAM Role Credentials
- This procedure applies to all AWS Lambda runtimes except the Node.js 10.x runtime.
The Node.js 10.x runtime runs onAmazon Linux release 2 (Karoo)
and does not have Python pre-installed.
To connect from your Lambda function to a CodeCommit repository over HTTPS using the AWS Lambda IAM role credentials (without providing a username and password), perform the following steps:
- Make Git available in the execution environment of your Lambda function.
Choose one of the following options:- Compile the latest sources of Git and include the binaries into the deployment package of your Lambda function. If you want to keep your deployment package small, you can include the binaries in an AWS Lambda layer and attach this layer to the execution environment of your Lambda function. You must build your binaries for the matching version of Amazon Linux or link them statically.
- Download Git in your Lambda function during its execution.
- Include the Git credential helper into the deployment package of your Lambda function.
- In this procedure, you do not use the AWS CLI credential helper. Instead of this, you use a small Python script that does not have any third-party dependencies.
- Download the script
credential-helper.py
.
For further details about this script, see Appendix A, Git Credential Helper to Connect to CodeCommit Repositories from a Lambda Function (Python). - Add the credential helper to the root directory of the deployment package
~/lambda.zip
of your Lambda function.chmod 755 credential-helper.py && zip -g ~/lambda.zip credential-helper.py
- Set up the credential helper for Git.
- Create the Git configuration file
.gitconfig
with the following contents:[credential] helper = /var/task/credential-helper.py UseHttpPath = true
- Add
.gitconfig
to the root directory of the deployment package of your Lambda function.zip -g ~/lambda.zip .gitconfig
- Your Git configuration file will be available at
/var/task/.gitconfig
in the execution environment of your Lambda function. You have to setHOME=/var/task
when you run the Git client. Otherwise, Git will not use this file.
- Your Git configuration file will be available at
- Create the Git configuration file
- Add to the deployment package
~/lambda.zip
of your Lambda function the source code that executes Git commands against your CodeCommit repository. - In the IAM role of your Lambda function, grant permissions for the required CodeCommit actions.
For example, if you want to clone your CodeCommit repository, grant permissions for thecodecommit:GitPull
action.
Appendix A, Git Credential Helper to Connect to CodeCommit Repositories from a Lambda Function (Python)
The following Python script can be used as a Git credential helper to connect to CodeCommit repositories in a Lambda function. The code is compatible with Python 2.7, Python 3.6, and Python 3.7. It does not have botocore
, boto3
, or any other third-party dependency. Only the Python standard library is used.
Python 2.7 is pre-installed in all AWS Lambda runtimes except the Node.js 10.x runtime. Thus, you can use this script not only in Python runtimes but also in any other runtime except the Node.js 10.x runtime.
Also, you can use this script without any modification on a Linux-based EC2 instance that has an IAM role attached and Python installed.
#!/usr/bin/env python
# CloudBriefly.com
from __future__ import print_function
from datetime import datetime
import hashlib
import hmac
import json
import sys
if sys.version_info[0] > 2:
from urllib.request import urlopen
from configparser import ConfigParser
else:
from urllib2 import urlopen
from ConfigParser import ConfigParser
from StringIO import StringIO
def sign(key, message):
return hmac.new(key, message.encode('utf-8'), hashlib.sha256).digest()
def generate_codecommit_repo_credentials():
now = datetime.utcnow()
amz_date = now.strftime('%Y%m%dT%H%M%S')
date_stamp = now.strftime('%Y%m%d')
# Get the IAM Role credentials
metadata_url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'
iam_role = urlopen(metadata_url).read().decode('utf-8')
credentials = json.load(urlopen(metadata_url + iam_role))
# Parameteres passed by the command-line Git client
git_parameters_string = '[repo]\n' + sys.stdin.read()
git_parameters = ConfigParser()
if sys.version_info[0] > 2:
git_parameters.read_string(git_parameters_string)
else:
git_parameters.readfp(StringIO(git_parameters_string))
host = git_parameters.get('repo', 'host').split(':')[0]
path = git_parameters.get('repo', 'path')
region = host.split('.')[1]
# Generate the username and password for the CodeCommit repository
credential_scope = '%s/%s/codecommit/aws4_request' % (date_stamp, region)
canonical_request = 'GIT\n/%s\n\nhost:%s\n\nhost\n' % (path, host)
string_to_sign = 'AWS4-HMAC-SHA256\n%s\n%s\n%s' % (
amz_date, credential_scope,
hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
)
signing_key = \
sign(sign(sign(sign(('AWS4' + credentials['SecretAccessKey']).encode('utf-8'),
date_stamp),
region),
'codecommit'),
'aws4_request')
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'),
hashlib.sha256).hexdigest()
print('username=%s%%%s' % (credentials['AccessKeyId'], credentials['Token']))
print('password=%sZ%s' % (amz_date, signature))
generate_codecommit_repo_credentials()
- In the IAM role of your Lambda function (or EC2 instance), you must grant permissions for the required CodeCommit actions. For example, for the
codecommit:GitPull
action.