Best practices for lambda layer dependencies

1

Hi all,

We recently started using the OpenTelemetry lambda layer for python: https://aws-otel.github.io/docs/getting-started/lambda/lambda-python in our serverless applications. We've encountered an issue with dependencies in a few of our projects, where the version of a particular dependency required by the lambda layer would conflict with the version installed in the lambda function itself. For example, the lambda layer had a requirement for protobuf>=3.15.0, whereas our application was using 3.13.0, causing the following error in the logs:

2022-06-01T15:59:35.215-04:00	Configuration of configurator failed
	2022-06-01T15:59:35.215-04:00	Traceback (most recent call last):
	2022-06-01T15:59:35.215-04:00	File "/opt/python/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 105, in _load_configurators
	2022-06-01T15:59:35.215-04:00	entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 215, in configure
	2022-06-01T15:59:35.215-04:00	self._configure(**kwargs)
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 231, in _configure
	2022-06-01T15:59:35.215-04:00	_initialize_components(kwargs.get("auto_instrumentation_version"))
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 181, in _initialize_components
	2022-06-01T15:59:35.215-04:00	trace_exporters, log_exporters = _import_exporters(
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 149, in _import_exporters
	2022-06-01T15:59:35.215-04:00	for (exporter_name, exporter_impl,) in _import_config_components(
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 136, in _import_config_components
	2022-06-01T15:59:35.215-04:00	component_impl = entry_point.load()
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 2470, in load
	2022-06-01T15:59:35.215-04:00	self.require(*args, **kwargs)
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 2493, in require
	2022-06-01T15:59:35.215-04:00	items = working_set.resolve(reqs, env, installer, extras=self.extras)
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 800, in resolve
	2022-06-01T15:59:35.215-04:00	raise VersionConflict(dist, req).with_context(dependent_req)
	2022-06-01T15:59:35.215-04:00	pkg_resources.ContextualVersionConflict: (protobuf 3.13.0 (/var/task), Requirement.parse('protobuf>=3.15.0'), {'googleapis-common-protos'})
	2022-06-01T15:59:35.215-04:00	Failed to auto initialize opentelemetry
	2022-06-01T15:59:35.215-04:00	Traceback (most recent call last):
	2022-06-01T15:59:35.215-04:00	File "/opt/python/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 123, in initialize
	2022-06-01T15:59:35.215-04:00	_load_configurators()
	2022-06-01T15:59:35.215-04:00	File "/opt/python/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 109, in _load_configurators
	2022-06-01T15:59:35.215-04:00	raise exc
	2022-06-01T15:59:35.215-04:00	File "/opt/python/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 105, in _load_configurators
	2022-06-01T15:59:35.215-04:00	entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 215, in configure
	2022-06-01T15:59:35.215-04:00	self._configure(**kwargs)
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 231, in _configure
	2022-06-01T15:59:35.215-04:00	_initialize_components(kwargs.get("auto_instrumentation_version"))
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 181, in _initialize_components
	2022-06-01T15:59:35.215-04:00	trace_exporters, log_exporters = _import_exporters(
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 149, in _import_exporters
	2022-06-01T15:59:35.215-04:00	for (exporter_name, exporter_impl,) in _import_config_components(
	2022-06-01T15:59:35.215-04:00	File "/var/task/opentelemetry/sdk/_configuration/__init__.py", line 136, in _import_config_components
	2022-06-01T15:59:35.215-04:00	component_impl = entry_point.load()
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 2470, in load
	2022-06-01T15:59:35.215-04:00	self.require(*args, **kwargs)
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 2493, in require
	2022-06-01T15:59:35.215-04:00	items = working_set.resolve(reqs, env, installer, extras=self.extras)
	2022-06-01T15:59:35.215-04:00	File "/var/task/pkg_resources/__init__.py", line 800, in resolve
	2022-06-01T15:59:35.215-04:00	raise VersionConflict(dist, req).with_context(dependent_req)
	2022-06-01T15:59:35.266-04:00	pkg_resources.ContextualVersionConflict: (protobuf 3.13.0 (/var/task), Requirement.parse('protobuf>=3.15.0'), {'googleapis-common-protos'}) 

We've encountered the same issue with other libraries.

My question is whether there are any best practices or recommendations to deal with this issue a little bit better. Should the lambda layer maybe publish its list of dependencies for each version so that the service using it will know what to expect? I feel like this is introducing a very loose dependency that will be only caught in runtime, which seems problematic to me.

Hope it makes sense. I searched older posts and couldn't find anything relevant.

Many thanks in advance, Juan

asked 2 years ago144 views
No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions