Skip to content

Commit 66a2ca9

Browse files
committed
Merge branch 'mr/forestier/bump-python-version' into 'master'
Update the invalidate_cache lambda function See merge request it/e3-aws!44
2 parents 392ba87 + a3f304c commit 66a2ca9

File tree

10 files changed

+504
-82
lines changed

10 files changed

+504
-82
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Version 22.4.0 (2024-??-??) *NOT RELEASED YET*
22

33
* Add VPCv2 construct supporting private subnets over multiple AZ.
4+
* S3WebsiteDistribution can now define the python runtime for the lambda invalidating cloudfront cache.
45

56
# Version 22.3.0 (2024-24-01)
67

src/e3/aws/troposphere/cloudfront/__init__.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(
3636
bucket: Bucket | None = None,
3737
bucket_name: str | None = None,
3838
lambda_edge_function_arns: list[str] | None = None,
39+
lambda_runtime: str = "python3.9",
3940
root_object: str = "index.html",
4041
r53_route_from: list[tuple[str, str]] | None = None,
4142
logging_bucket: str | None = None,
@@ -58,6 +59,8 @@ def __init__(
5859
:param bucket_name: name of the bucket to create to host the website
5960
:param lambda_edge_function_arns: ARNs of Lambda@Edge functions to
6061
associate with the cloudfront distribution default cache behaviour
62+
:param lambda_runtime: the runtime of the lambda invalidation cache. It must be
63+
a Python runtime
6164
:param root_object: The object that you want CloudFront to request from
6265
your origin
6366
:param r53_route_from: list of (hosted_zone_id, domain_id) for which to
@@ -83,6 +86,7 @@ def __init__(
8386
self.certificate_arn = certificate_arn
8487
self.default_ttl = default_ttl
8588
self.lambda_edge_function_arns = lambda_edge_function_arns
89+
self.lambda_runtime = lambda_runtime
8690
self.root_object = root_object
8791
self.r53_route_from = r53_route_from
8892
self._origin_access_identity = None
@@ -257,21 +261,6 @@ def add_cache_invalidation(self, stack: Stack) -> list[AWSObject]:
257261
) as lf:
258262
lambda_code = lf.read().splitlines()
259263

260-
# Complete it with the part depending on the distribution id
261-
lambda_code.extend(
262-
[
263-
" client.create_invalidation(",
264-
Sub(
265-
" DistributionId='${distribution_id}',",
266-
distribution_id=self.id,
267-
),
268-
" InvalidationBatch={",
269-
" 'Paths': {'Quantity': 1, 'Items': path},",
270-
" 'CallerReference': str(time.time()),",
271-
" },",
272-
" )",
273-
]
274-
)
275264
lambda_function = Function(
276265
name_to_id(lambda_name),
277266
description=(
@@ -281,7 +270,8 @@ def add_cache_invalidation(self, stack: Stack) -> list[AWSObject]:
281270
handler="invalidate.handler",
282271
role=lambda_role,
283272
code_zipfile=Join("\n", lambda_code),
284-
runtime="python3.9",
273+
runtime=self.lambda_runtime,
274+
environment={"DISTRIBUTION_ID": Sub("${id}", id=self.id)},
285275
)
286276

287277
sns_topic = Topic(name=f"{self.name}-invalidation-topic")

src/e3/aws/troposphere/cloudfront/data/lambda_invalidate_head.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import boto3
2-
import time # noqa: F401
2+
import os
3+
import time
4+
5+
DISTRIBUTION_ID = os.environ["DISTRIBUTION_ID"]
36

47

58
def handler(event, context):
@@ -10,3 +13,10 @@ def handler(event, context):
1013
path.append("/")
1114
else:
1215
path.append("/" + items["s3"]["object"]["key"])
16+
client.create_invalidation(
17+
DistributionId=DISTRIBUTION_ID,
18+
InvalidationBatch={
19+
"Paths": {"Quantity": 1, "Items": path},
20+
"CallerReference": str(time.time()),
21+
},
22+
)

tests/tests_e3_aws/troposphere/cloudfront_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,24 @@ def test_s3_website_distribution_iam_path(stack: Stack) -> None:
127127
expected_template = json.load(fd)
128128

129129
assert stack.export()["Resources"] == expected_template
130+
131+
132+
def test_s3_website_distribution_python313(stack: Stack) -> None:
133+
"""Test Cloudfront S3WebsiteDistribution construct."""
134+
stack.add(
135+
S3WebsiteDistribution(
136+
name="test-s3w-dist",
137+
aliases=["test.s3w.com"],
138+
bucket_name="host-bucket",
139+
certificate_arn="acm_arn",
140+
default_ttl=360,
141+
lambda_edge_function_arns=["lamba_arn"],
142+
r53_route_from=[("hosted_zone_id", "test.s3w.com")],
143+
lambda_runtime="python3.13",
144+
)
145+
)
146+
147+
with open(os.path.join(TEST_DIR, "s3websitedistribution_py313.json")) as fd:
148+
expected_template = json.load(fd)
149+
150+
assert stack.export()["Resources"] == expected_template

tests/tests_e3_aws/troposphere/s3websitedistribution.json

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@
239239
"\n",
240240
[
241241
"import boto3",
242-
"import time # noqa: F401",
242+
"import os",
243+
"import time",
244+
"",
245+
"DISTRIBUTION_ID = os.environ[\"DISTRIBUTION_ID\"]",
243246
"",
244247
"",
245248
"def handler(event, context):",
@@ -251,19 +254,10 @@
251254
" else:",
252255
" path.append(\"/\" + items[\"s3\"][\"object\"][\"key\"])",
253256
" client.create_invalidation(",
254-
{
255-
"Fn::Sub": [
256-
" DistributionId='${distribution_id}',",
257-
{
258-
"distribution_id": {
259-
"Ref": "TestS3wDist"
260-
}
261-
}
262-
]
263-
},
257+
" DistributionId=DISTRIBUTION_ID,",
264258
" InvalidationBatch={",
265-
" 'Paths': {'Quantity': 1, 'Items': path},",
266-
" 'CallerReference': str(time.time()),",
259+
" \"Paths\": {\"Quantity\": 1, \"Items\": path},",
260+
" \"CallerReference\": str(time.time()),",
267261
" },",
268262
" )"
269263
]
@@ -278,6 +272,20 @@
278272
"Arn"
279273
]
280274
},
275+
"Environment": {
276+
"Variables": {
277+
"DISTRIBUTION_ID": {
278+
"Fn::Sub": [
279+
"${id}",
280+
{
281+
"id": {
282+
"Ref": "TestS3wDist"
283+
}
284+
}
285+
]
286+
}
287+
}
288+
},
281289
"FunctionName": "TestS3wDistCacheInvalidationLambda",
282290
"Runtime": "python3.9",
283291
"Handler": "invalidate.handler"

tests/tests_e3_aws/troposphere/s3websitedistribution_bucket.json

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@
239239
"\n",
240240
[
241241
"import boto3",
242-
"import time # noqa: F401",
242+
"import os",
243+
"import time",
244+
"",
245+
"DISTRIBUTION_ID = os.environ[\"DISTRIBUTION_ID\"]",
243246
"",
244247
"",
245248
"def handler(event, context):",
@@ -251,19 +254,10 @@
251254
" else:",
252255
" path.append(\"/\" + items[\"s3\"][\"object\"][\"key\"])",
253256
" client.create_invalidation(",
254-
{
255-
"Fn::Sub": [
256-
" DistributionId='${distribution_id}',",
257-
{
258-
"distribution_id": {
259-
"Ref": "TestS3wDist"
260-
}
261-
}
262-
]
263-
},
257+
" DistributionId=DISTRIBUTION_ID,",
264258
" InvalidationBatch={",
265-
" 'Paths': {'Quantity': 1, 'Items': path},",
266-
" 'CallerReference': str(time.time()),",
259+
" \"Paths\": {\"Quantity\": 1, \"Items\": path},",
260+
" \"CallerReference\": str(time.time()),",
267261
" },",
268262
" )"
269263
]
@@ -278,6 +272,20 @@
278272
"Arn"
279273
]
280274
},
275+
"Environment": {
276+
"Variables": {
277+
"DISTRIBUTION_ID": {
278+
"Fn::Sub": [
279+
"${id}",
280+
{
281+
"id": {
282+
"Ref": "TestS3wDist"
283+
}
284+
}
285+
]
286+
}
287+
}
288+
},
281289
"FunctionName": "TestS3wDistCacheInvalidationLambda",
282290
"Runtime": "python3.9",
283291
"Handler": "invalidate.handler"

tests/tests_e3_aws/troposphere/s3websitedistribution_iam_path.json

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@
239239
"\n",
240240
[
241241
"import boto3",
242-
"import time # noqa: F401",
242+
"import os",
243+
"import time",
244+
"",
245+
"DISTRIBUTION_ID = os.environ[\"DISTRIBUTION_ID\"]",
243246
"",
244247
"",
245248
"def handler(event, context):",
@@ -251,19 +254,10 @@
251254
" else:",
252255
" path.append(\"/\" + items[\"s3\"][\"object\"][\"key\"])",
253256
" client.create_invalidation(",
254-
{
255-
"Fn::Sub": [
256-
" DistributionId='${distribution_id}',",
257-
{
258-
"distribution_id": {
259-
"Ref": "TestS3wDist"
260-
}
261-
}
262-
]
263-
},
257+
" DistributionId=DISTRIBUTION_ID,",
264258
" InvalidationBatch={",
265-
" 'Paths': {'Quantity': 1, 'Items': path},",
266-
" 'CallerReference': str(time.time()),",
259+
" \"Paths\": {\"Quantity\": 1, \"Items\": path},",
260+
" \"CallerReference\": str(time.time()),",
267261
" },",
268262
" )"
269263
]
@@ -278,6 +272,20 @@
278272
"Arn"
279273
]
280274
},
275+
"Environment": {
276+
"Variables": {
277+
"DISTRIBUTION_ID": {
278+
"Fn::Sub": [
279+
"${id}",
280+
{
281+
"id": {
282+
"Ref": "TestS3wDist"
283+
}
284+
}
285+
]
286+
}
287+
}
288+
},
281289
"FunctionName": "TestS3wDistCacheInvalidationLambda",
282290
"Runtime": "python3.9",
283291
"Handler": "invalidate.handler"

tests/tests_e3_aws/troposphere/s3websitedistribution_logging.json

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@
249249
"\n",
250250
[
251251
"import boto3",
252-
"import time # noqa: F401",
252+
"import os",
253+
"import time",
254+
"",
255+
"DISTRIBUTION_ID = os.environ[\"DISTRIBUTION_ID\"]",
253256
"",
254257
"",
255258
"def handler(event, context):",
@@ -261,19 +264,10 @@
261264
" else:",
262265
" path.append(\"/\" + items[\"s3\"][\"object\"][\"key\"])",
263266
" client.create_invalidation(",
264-
{
265-
"Fn::Sub": [
266-
" DistributionId='${distribution_id}',",
267-
{
268-
"distribution_id": {
269-
"Ref": "TestS3wDist"
270-
}
271-
}
272-
]
273-
},
267+
" DistributionId=DISTRIBUTION_ID,",
274268
" InvalidationBatch={",
275-
" 'Paths': {'Quantity': 1, 'Items': path},",
276-
" 'CallerReference': str(time.time()),",
269+
" \"Paths\": {\"Quantity\": 1, \"Items\": path},",
270+
" \"CallerReference\": str(time.time()),",
277271
" },",
278272
" )"
279273
]
@@ -288,6 +282,20 @@
288282
"Arn"
289283
]
290284
},
285+
"Environment": {
286+
"Variables": {
287+
"DISTRIBUTION_ID": {
288+
"Fn::Sub": [
289+
"${id}",
290+
{
291+
"id": {
292+
"Ref": "TestS3wDist"
293+
}
294+
}
295+
]
296+
}
297+
}
298+
},
291299
"FunctionName": "TestS3wDistCacheInvalidationLambda",
292300
"Runtime": "python3.9",
293301
"Handler": "invalidate.handler"

tests/tests_e3_aws/troposphere/s3websitedistribution_logging_default.json

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@
249249
"\n",
250250
[
251251
"import boto3",
252-
"import time # noqa: F401",
252+
"import os",
253+
"import time",
254+
"",
255+
"DISTRIBUTION_ID = os.environ[\"DISTRIBUTION_ID\"]",
253256
"",
254257
"",
255258
"def handler(event, context):",
@@ -261,19 +264,10 @@
261264
" else:",
262265
" path.append(\"/\" + items[\"s3\"][\"object\"][\"key\"])",
263266
" client.create_invalidation(",
264-
{
265-
"Fn::Sub": [
266-
" DistributionId='${distribution_id}',",
267-
{
268-
"distribution_id": {
269-
"Ref": "TestS3wDist"
270-
}
271-
}
272-
]
273-
},
267+
" DistributionId=DISTRIBUTION_ID,",
274268
" InvalidationBatch={",
275-
" 'Paths': {'Quantity': 1, 'Items': path},",
276-
" 'CallerReference': str(time.time()),",
269+
" \"Paths\": {\"Quantity\": 1, \"Items\": path},",
270+
" \"CallerReference\": str(time.time()),",
277271
" },",
278272
" )"
279273
]
@@ -288,6 +282,20 @@
288282
"Arn"
289283
]
290284
},
285+
"Environment": {
286+
"Variables": {
287+
"DISTRIBUTION_ID": {
288+
"Fn::Sub": [
289+
"${id}",
290+
{
291+
"id": {
292+
"Ref": "TestS3wDist"
293+
}
294+
}
295+
]
296+
}
297+
}
298+
},
291299
"FunctionName": "TestS3wDistCacheInvalidationLambda",
292300
"Runtime": "python3.9",
293301
"Handler": "invalidate.handler"

0 commit comments

Comments
 (0)