Skip to content

Instantly share code, notes, and snippets.

@asfourco
Created March 6, 2020 12:23
Show Gist options
  • Save asfourco/4dfe67cf16f5255dfd56fd0774d0b004 to your computer and use it in GitHub Desktop.
Save asfourco/4dfe67cf16f5255dfd56fd0774d0b004 to your computer and use it in GitHub Desktop.
Building AWS CDK Lambda Layer - Python
{
"app": "python3 stack.py",
"out": "cdk.out"
}
import setuptools
import os
import distutils.cmd
import distutils.log
import subprocess # nosec
#####
# PACKAGE VERSION NUMBER
version = "0.0.1"
# PACKAGE NAME
pkg_name = " PACKAGE NAME "
#####
readme = os.path.join(os.path.dirname(__file__), "README.md")
with open(readme, "r") as fh:
long_description = fh.read()
class CDKBuild(distutils.cmd.Command):
""" A custom command to run build integration layer for cdk deployment """
description = "create integration assert layer for cdk deployment"
user_options = [
("output-dir=", "o", "output directory"),
]
def initialize_options(self):
self.output_dir = None
def finalize_options(self):
if not os.path.isdir(self.output_dir):
raise Exception(f"Output directory does not exist: {self.output_dir}")
def run(self):
""" Create opt dir"""
cur_dir = os.getcwd()
dist_dir = os.path.join(cur_dir, "dist")
"""Run command."""
# Build distribution package
command = ["python", "setup.py", "sdist", "--format=zip"]
self.announce("Building distribution package", level=distutils.log.INFO)
subprocess.check_call(command) # nosec
# Clean output dir
os.chdir(self.output_dir)
command = ["rm", "-rf", "python", "layer.zip"]
self.announce(f"Cleaning output dir {self.output_dir}", level=distutils.log.INFO)
subprocess.check_call(command) # nosec
# Install into ./opt
dist_file = os.path.join(dist_dir, f"{pkg_name}-{version}.zip")
command = ["pip", "install", dist_file, "-t", "python"]
self.announce("Installing distribution package into ./opt", level=distutils.log.INFO)
subprocess.check_call(command) # nosec
# zip into assert layer
command = ["zip", "-r", "layer.zip", "python"]
self.announce("Creating layer asset archive", level=distutils.log.INFO)
subprocess.check_call(command) # nosec
class CDKDeploy(distutils.cmd.Command):
""" A custom command to run cdk deployment """
description = "Deploy CDK layer"
user_options = [("action=", "a", "CDK Action")]
def initialize_options(self):
self.action = None
def finalize_options(self):
if not self.action:
raise Exception("Must specify a valid CDK action")
if self.action not in ["ls", "diff", "deploy"]:
raise Exception("Valid CDK Actions are: ls, diff, or deploy")
if not os.path.exists(os.path.join(os.getcwd(), "opt/layer.zip")):
raise Exception("Layer Assert does not exist! Please run `python setup.py cdk_build --output-dir opt`")
def run(self):
"""Run command."""
command = ["cdk", self.action]
self.announce(f"Running CDK action: {self.action}", level=distutils.log.INFO)
subprocess.run(command) # nosec
setuptools.setup(
name=pkg_name,
version=version,
author=" AUTHOR ",
description="PACKAGE DESCRIPTION",
long_description=long_description,
long_description_content_type="text/markdown",
python_requires=">=3.6",
install_requires=[
"aws-cdk.core",
"aws-cdk.aws-lambda",
# Add the libraries that you need, e.g.,
"requests",
"mypy",
"flake8",
"black",
"bandit"
],
zip_safe=True,
packages=setuptools.find_packages(exclude=["cdk*", "opt", "utils", "test*"]),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
cmdclass={"cdk_build": CDKBuild, "cdk_deploy": CDKDeploy},
)
from aws_cdk.aws_lambda import Runtime, Code, LayerVersion, LayerVersionPermission
from aws_cdk.core import Stack, CfnOutput, App
#### MODIFY THIS PART
name = "_ LAYER NAME _"
description = " ADD YOUR DESCRIPTION "
org_id = " ORGANISATION ID "
#########
app = App()
stack = Stack(app, "AWSLambdaLayer", stack_name=name)
layer = LayerVersion(
stack,
f"{name}_layer",
compatible_runtimes=[Runtime.PYTHON_3_6, Runtime.PYTHON_3_7, Runtime.PYTHON_3_8],
code=Code.from_asset("opt/layer.zip"),
layer_version_name=name,
description=description",
)
layer.add_permission(id="allOrganisationAccounts", account_id="*", organization_id=org_id)
app.synth()
@asfourco
Copy link
Author

asfourco commented Mar 6, 2020

To build and deploy the layer:

$ source .env/bin/activate # ensure environment is activated
$ python setup.py cdk_build --output-dir opt
$ python setup.py cdk_deploy --action deploy

One can also pass in the regular cdk actions to cdk_deploy, e.g.,

# cdk ls
$ python setup.py cdk_deploy --action ls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment