Skip to content

Commit 9badf12

Browse files
committed
some tlc
1 parent 111a7c6 commit 9badf12

11 files changed

Lines changed: 1054 additions & 210 deletions

.github/workflows/ci.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
lint-and-test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.14"
21+
22+
- name: Install yq
23+
run: |
24+
sudo wget -qO /usr/local/bin/yq \
25+
https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
26+
sudo chmod +x /usr/local/bin/yq
27+
yq --version
28+
29+
- name: Install Python tooling
30+
run: |
31+
python -m pip install --upgrade pip
32+
pip install ruff yamllint cfn-lint pytest pyyaml botocore
33+
34+
- name: Ruff lint
35+
run: ruff check .
36+
37+
- name: Ruff format check
38+
run: ruff format --check .
39+
40+
- name: yamllint
41+
run: yamllint .
42+
43+
- name: cfn-lint
44+
run: cfn-lint CFN-CR-PythonLambdaLayer.yaml CFN-CR-PythonLambdaLayer-SampleUsage.yaml
45+
46+
- name: Embedded code matches tracked file
47+
run: python scripts/check_embedded_code.py
48+
49+
- name: pytest
50+
run: pytest -v

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
__pycache__/
2+
*.py[cod]
3+
.pytest_cache/
4+
.ruff_cache/

.yamllint.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
extends: default
2+
3+
rules:
4+
line-length:
5+
max: 160
6+
level: warning
7+
# CFN templates and their inline scripts break default indentation rules;
8+
# relax to avoid false positives on block scalars.
9+
indentation:
10+
spaces: 2
11+
indent-sequences: consistent
12+
# The inline ZipFile uses trailing whitespace we don't control.
13+
trailing-spaces: disable
14+
comments:
15+
min-spaces-from-content: 1
16+
document-start: disable
17+
truthy:
18+
check-keys: false

CFN-CR-PythonLambdaLayer-SampleUsage.yaml

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,47 @@ Resources:
1212
EmptyLambdaLayer:
1313
Properties:
1414
ServiceToken:
15-
Fn::ImportValue: !Sub "cfn:lambdalayer:${AWS::Region}:arn"
15+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
1616
Name: test-gracefull-exit
17-
Region: !Ref "AWS::Region"
1817
Type: Custom::LayerBuilder
1918

2019
Boto3LambdaLayer:
2120
Properties:
2221
ServiceToken:
23-
Fn::ImportValue: !Sub "cfn:lambdalayer:${AWS::Region}:arn"
22+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
2423
Name: boto3-latest
25-
Region: !Ref "AWS::Region"
2624
requirements:
2725
- boto3
2826
Type: Custom::LayerBuilder
2927

30-
TropoLambdaLayer:
28+
RequestsLambdaLayer:
3129
Properties:
3230
ServiceToken:
33-
Fn::ImportValue: !Sub "cfn:lambdalayer:${AWS::Region}:arn"
34-
Name: cfn-account-policy
35-
Region: !Ref "AWS::Region"
31+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
32+
Name: requests-latest
3633
requirements:
37-
- "troposphere>2.3.0"
38-
- "awacs==0.7.2"
34+
- requests
35+
Type: Custom::LayerBuilder
36+
37+
# Pydantic has a compiled pydantic-core dependency; the builder's arch must
38+
# match the consumer function's arch. x86_64 builder → x86_64 consumer.
39+
PydanticLambdaLayer:
40+
Properties:
41+
ServiceToken:
42+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
43+
Name: pydantic-latest
44+
requirements:
45+
- pydantic
3946
Type: Custom::LayerBuilder
4047

4148
InlineCodeLambdaLayer:
4249
Properties:
4350
ServiceToken:
44-
Fn::ImportValue: !Sub "cfn:lambdalayer:${AWS::Region}:arn"
51+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
4552
Name: inline-code-only
46-
Region: !Ref "AWS::Region"
4753
filename: eratosthenes.py
4854
filecontent:
49-
Fn::Base64: !Sub |
55+
Fn::Base64: |
5056
def sieve(n):
5157
# https://wikipedia.org/wiki/Sieve_of_Eratosthenes
5258
return sorted(
@@ -61,19 +67,29 @@ Resources:
6167
InlineCodeWithPipPackageLambdaLayer:
6268
Properties:
6369
ServiceToken:
64-
Fn::ImportValue: !Sub "cfn:lambdalayer:${AWS::Region}:arn"
70+
Fn::ImportValue: !Sub "cfn:lambdalayer-x86-64:${AWS::Region}:arn"
6571
Name: inline-code-and-requirements
66-
Region: !Ref "AWS::Region"
6772
requirements:
6873
- python-whois
6974
filename: module.py
7075
filecontent:
71-
Fn::Base64: !Sub |
76+
Fn::Base64: |
7277
from whois import whois
7378
def examine(domain):
7479
return whois(domain)
7580
Type: Custom::LayerBuilder
7681

82+
# Same requirements, different arch: call the arm64 builder. C extensions
83+
# get built natively for arm64 so Graviton consumer functions work.
84+
Arm64BotoLambdaLayer:
85+
Properties:
86+
ServiceToken:
87+
Fn::ImportValue: !Sub "cfn:lambdalayer-arm64:${AWS::Region}:arn"
88+
Name: boto3-latest-arm64
89+
requirements:
90+
- boto3
91+
Type: Custom::LayerBuilder
92+
7793
LambdaExecutionRole:
7894
Type: 'AWS::IAM::Role'
7995
Properties:
@@ -105,24 +121,25 @@ Resources:
105121
Description: 'Show lib version from the layers'
106122
Code:
107123
ZipFile: |
108-
import troposphere
109124
import boto3
125+
import pydantic
126+
import requests
110127
from lambdalayer.module import examine
111128
from lambdalayer.eratosthenes import sieve
112129
113130
def lambda_handler(event, context):
114-
print("Tropo version: {}".format(troposphere.__version__))
115-
print("Boto3 version: {}".format(boto3.__version__))
116-
print("Sieve of Eratosthenes from 10: {}".format(sieve(10)))
117-
print("WhoIs example.com: {}".format(examine('example.com')))
118-
119-
131+
print(f"boto3 version: {boto3.__version__}")
132+
print(f"pydantic version: {pydantic.VERSION}")
133+
print(f"requests version: {requests.__version__}")
134+
print(f"Sieve of Eratosthenes from 10: {sieve(10)}")
135+
print(f"WhoIs example.com: {examine('example.com')}")
120136
Handler: index.lambda_handler
121-
Runtime: python3.7
137+
Runtime: python3.14
122138
Timeout: 60
123139
Role: !GetAtt LambdaExecutionRole.Arn
124140
Layers:
125141
- !GetAtt Boto3LambdaLayer.Arn
126-
- !GetAtt TropoLambdaLayer.Arn
142+
- !GetAtt RequestsLambdaLayer.Arn
143+
- !GetAtt PydanticLambdaLayer.Arn
127144
- !GetAtt InlineCodeWithPipPackageLambdaLayer.Arn
128145
- !GetAtt InlineCodeLambdaLayer.Arn

0 commit comments

Comments
 (0)