Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sam build fails when required to install some 3rd party libraries in requirements.txt #1380

Closed
wes3985 opened this issue Aug 28, 2019 · 18 comments

Comments

@wes3985
Copy link

wes3985 commented Aug 28, 2019

Description

I'm trying to build a lambda using aws sam cli which requires the 'paramiko' package. However when I add it to the requirements.txt file in the normal way it fails at the build step with the following error output:

`2019-08-28 10:26:09 Building resource 'HelloWorldFunction'
2019-08-28 10:26:09 Running PythonPipBuilder:ResolveDependencies

Build Failed
Error: PythonPipBuilder:ResolveDependencies - {pynacl==1.3.0(wheel), bcrypt==3.1.7(wheel), cryptography==2.7(wheel)}`

Steps to reproduce

sam init --runtime python3.6 --name TestParamiko

in requirements.txt add:

paramiko

cd TestParamiko

sam build

Observed result (output with --debug)

2019-08-28 10:27:20 Using SAM Template at C:\Users\ww\workspace\AWS-SAM-CLI-Lambdas-and-Layers\TestParamiko\template.yaml
2019-08-28 10:27:20 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-08-28 10:27:20 Changing event name from before-call.apigateway to before-call.api-gateway
2019-08-28 10:27:20 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-08-28 10:27:20 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-08-28 10:27:20 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-08-28 10:27:20 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-08-28 10:27:20 Changing event name from docs..autoscaling.CreateLaunchConfiguration.complete-section to docs..auto-scaling.CreateLaunchConfiguration.complete-section
2019-08-28 10:27:20 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-08-28 10:27:20 Changing event name from docs..logs.CreateExportTask.complete-section to docs..cloudwatch-logs.CreateExportTask.complete-section
2019-08-28 10:27:20 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-08-28 10:27:20 Changing event name from docs..cloudsearchdomain.Search.complete-section to docs..cloudsearch-domain.Search.complete-section
2019-08-28 10:27:20 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-08-28 10:27:20 Changing event name from before-call.apigateway to before-call.api-gateway
2019-08-28 10:27:20 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-08-28 10:27:20 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-08-28 10:27:20 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-08-28 10:27:20 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-08-28 10:27:20 Changing event name from docs..autoscaling.CreateLaunchConfiguration.complete-section to docs..auto-scaling.CreateLaunchConfiguration.complete-section
2019-08-28 10:27:20 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-08-28 10:27:20 Changing event name from docs..logs.CreateExportTask.complete-section to docs..cloudwatch-logs.CreateExportTask.complete-section
2019-08-28 10:27:20 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-08-28 10:27:20 Changing event name from docs..cloudsearchdomain.Search.complete-section to docs..cloudsearch-domain.Search.complete-section
2019-08-28 10:27:20 'build' command is called
2019-08-28 10:27:20 No Parameters detected in the template
2019-08-28 10:27:20 2 resources found in the template
2019-08-28 10:27:20 Found Serverless function with name='HelloWorldFunction' and CodeUri='hello_world/'
2019-08-28 10:27:21 Building resource 'HelloWorldFunction'
2019-08-28 10:27:21 Loading workflow module 'aws_lambda_builders.workflows'
2019-08-28 10:27:21 Registering workflow 'PythonPipBuilder' with capability 'Capability(language='python', dependency_manager='pip', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'NodejsNpmBuilder' with capability 'Capability(language='nodejs', dependency_manager='npm', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'RubyBundlerBuilder' with capability 'Capability(language='ruby', dependency_manager='bundler', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'GoDepBuilder' with capability 'Capability(language='go', dependency_manager='dep', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'GoModulesBuilder' with capability 'Capability(language='go', dependency_manager='modules', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'JavaGradleWorkflow' with capability 'Capability(language='java', dependency_manager='gradle', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'JavaMavenWorkflow' with capability 'Capability(language='java', dependency_manager='maven', application_framework=None)'
2019-08-28 10:27:21 Registering workflow 'DotnetCliPackageBuilder' with capability 'Capability(language='dotnet', dependency_manager='cli-package', application_framework=None)'
2019-08-28 10:27:21 Found workflow 'PythonPipBuilder' to support capabilities 'Capability(language='python', dependency_manager='pip', application_framework=None)'
2019-08-28 10:27:21 Running workflow 'PythonPipBuilder'
2019-08-28 10:27:21 Running PythonPipBuilder:ResolveDependencies
2019-08-28 10:27:21 calling pip download -r C:\Users\ww\workspace\AWS-SAM-CLI-Lambdas-and-Layers\TestParamiko\hello_world\requirements.txt --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp
2019-08-28 10:27:31 Full dependency closure: {paramiko==2.6.0(wheel), pycparser==2.19(sdist), bcrypt==3.1.7(wheel), certifi==2019.6.16(wheel), requests==2.22.0(wheel), cffi==1.12.3(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel),
cryptography==2.7(wheel), pynacl==1.3.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:31 initial compatible: {paramiko==2.6.0(wheel), requests==2.22.0(wheel), certifi==2019.6.16(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:31 initial incompatible: {pycparser==2.19(sdist), bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel), cffi==1.12.3(wheel)}
2019-08-28 10:27:31 Downloading missing wheels: {pycparser==2.19(sdist), bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel), cffi==1.12.3(wheel)}
2019-08-28 10:27:31 calling pip download --only-binary=:all: --no-deps --platform manylinux1_x86_64 --implementation cp --abi cp36m --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp pycparser==2.19
2019-08-28 10:27:34 calling pip download --only-binary=:all: --no-deps --platform manylinux1_x86_64 --implementation cp --abi cp36m --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp bcrypt==3.1.7
2019-08-28 10:27:36 calling pip download --only-binary=:all: --no-deps --platform manylinux1_x86_64 --implementation cp --abi cp36m --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp cryptography==2.7
2019-08-28 10:27:39 calling pip download --only-binary=:all: --no-deps --platform manylinux1_x86_64 --implementation cp --abi cp36m --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp pynacl==1.3.0
2019-08-28 10:27:41 calling pip download --only-binary=:all: --no-deps --platform manylinux1_x86_64 --implementation cp --abi cp36m --dest C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp cffi==1.12.3
2019-08-28 10:27:43 compatible wheels after second download pass: {paramiko==2.6.0(wheel), certifi==2019.6.16(wheel), requests==2.22.0(wheel), cffi==1.12.3(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:43 Build missing wheels from sdists (C compiling True): {pycparser==2.19(sdist)}
2019-08-28 10:27:43 calling pip wheel --no-deps --wheel-dir C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp C:\Users\ww\AppData\Local\Temp\tmpbjd2m3hp\pycparser-2.19.tar.gz
2019-08-28 10:27:50 compatible after building wheels (no C compiling): {paramiko==2.6.0(wheel), pycparser==2.19(wheel), certifi==2019.6.16(wheel), requests==2.22.0(wheel), cffi==1.12.3(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:50 Build missing wheels from sdists (C compiling False): set()
2019-08-28 10:27:50 compatible after building wheels (C compiling): {paramiko==2.6.0(wheel), pycparser==2.19(wheel), certifi==2019.6.16(wheel), requests==2.22.0(wheel), cffi==1.12.3(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:50 Final compatible: {paramiko==2.6.0(wheel), pycparser==2.19(wheel), certifi==2019.6.16(wheel), requests==2.22.0(wheel), cffi==1.12.3(wheel), urllib3==1.25.3(wheel), chardet==3.0.4(wheel), asn1crypto==0.24.0(wheel), idna==2.8(wheel), six==1.12.0(wheel)}
2019-08-28 10:27:50 Final incompatible: {cffi==1.12.3(wheel), cryptography==2.7(wheel), bcrypt==3.1.7(wheel), pynacl==1.3.0(wheel)}
2019-08-28 10:27:50 Final missing wheels: {bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel)}
2019-08-28 10:27:50 PythonPipBuilder:ResolveDependencies failed
Traceback (most recent call last):
File "c:\users\ww\appdata\local\programs\python\python36\lib\site-packages\aws_lambda_builders\workflows\python_pip\actions.py", line 39, in execute
self.scratch_dir
File "c:\users\ww\appdata\local\programs\python\python36\lib\site-packages\aws_lambda_builders\workflows\python_pip\packager.py", line 143, in build_dependencies
requirements_path, artifacts_dir_path, scratch_dir_path)
File "c:\users\ww\appdata\local\programs\python\python36\lib\site-packages\aws_lambda_builders\workflows\python_pip\packager.py", line 212, in build_site_packages
raise MissingDependencyError(packages_without_wheels)
aws_lambda_builders.workflows.python_pip.packager.MissingDependencyError: {bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel)}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "c:\users\ww\appdata\local\programs\python\python36\lib\site-packages\aws_lambda_builders\workflow.py", line 248, in run
action.execute()
File "c:\users\ww\appdata\local\programs\python\python36\lib\site-packages\aws_lambda_builders\workflows\python_pip\actions.py", line 42, in execute
raise ActionFailedError(str(ex))
aws_lambda_builders.actions.ActionFailedError: {bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel)}

Build Failed
Error: PythonPipBuilder:ResolveDependencies - {bcrypt==3.1.7(wheel), cryptography==2.7(wheel), pynacl==1.3.0(wheel)}

Expected result

I expected the build to complete as usual for packaging and deployment

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: windows 10
  2. sam --version: SAM CLI, version 0.17.0

I wondered if it would work if I ran the build command with the --use-container flag but this also failed:

sam build --template template.yaml --use-container

OUTPUT

2019-08-28 10:49:07 Starting Build inside a container
2019-08-28 10:49:07 Building resource 'HelloWorldFunction'

Fetching lambci/lambda:build-python3.6 Docker container image......
2019-08-28 10:49:09 Mounting C:\Users\ww\workspace\AWS-SAM-CLI-Lambdas-and-Layers\TestParamiko\hello_world as /tmp/samcli/source:ro,delegated inside runtime container

Build Failed
Error: PythonPipBuilder:ResolveDependencies - Requirements file not found: /tmp/samcli/source/requirements.txt
Running PythonPipBuilder:ResolveDependencies

Any help how to resolve this would be great, I posted on stackoverflow but no-one has picked it up https://stackoverflow.com/questions/57672859/aws-sam-build-not-able-to-build-packages-which-require-paramiko-due-to-error-p?noredirect=1#comment101801423_57672859. The steps posted here reproduce the exact issue.

If there is another library other than paramiko or pysftp that could be used for SFTP in a lambda that I could use that as a work around? However it would need to have different dependencies.

Many thanks for any help.

@sriram-mv
Copy link
Contributor

We had integration tests that build dependencies like cryptography, till we removed it because we couldnt build pycparser within the container. This aws/aws-lambda-builders#34 fixes that.

But its wierd that docker is not able to find the requirements.txt file, are you able to re-produce this on a non-windows machine? I'm trying to think if this is a windows path issue.

another way to check if the docker container has the right environment to build, is to volume mount and run it interactively with bash and install dependencies.

Do all sam builds within container fail? irrespective of contents of the requirements.txt file.

@wes3985
Copy link
Author

wes3985 commented Aug 29, 2019

Thanks for getting back to me, unfortunately our whole team is windows based so it would be hard for us to use a non-windows machine, unless we set up a cloud9 instance and migrated a chunk of our dev or something.

I'm not entirely sure how to best follow up the with the link you posted? If I understand, is this now submitted as something to be fixed?

I have only a basic understanding of docker unfortunately but am more than happy to give your suggestion of running interactively a try. I ran the following and paramiko and all dependencies were successfully installed:

docker run --rm -it lambci/lambda:build-python3.6 bash

and then:

pip install paramiko

I got this from here: https://hub.docker.com/r/lambci/lambda/

Is there a different image I should try perhaps or is this one ok?

I believe the app I want to package and deploy isn't visible from within the interactive container, if I could somehow mount the root directory of the app inside the container then could I build from there? I'm guessing I would then have to somehow get the build out of the container in order to push to cloudformation, OR set up the container with my aws-sam user details and push from there? Probably I'd need to build the container with ports to communicate with the host machine and/or aws? Please excuse my lack of docker experience but is this a plausible workaround? I would rather check first as this could take a docker newb quite a lot of time to figure out which could be a lot of wasted time if its not going to work?

Yes all sam builds with the --use-container arg fail irrespective of requirements.txt contents, I tried with an empty file and one with libraries which I have successfully deployed before (without --use-container) and all return the above error. I'll keep digging around to see if I can resolve any windows path error. If you have any other suggestions I'd be really grateful. Many thanks!

@wes3985
Copy link
Author

wes3985 commented Aug 29, 2019

Ok, so I tried the volume mount the app in a docker container and unfortunately windows 10 can be very fiddly to get this to work. Basically you can't have dashes or underscores in your path to your app ( which I happen to have in my code repo path! ) this confused me for a while, but I eventually got the mount to work by copying the root directory of my app to a new directory and running the following:

docker run --rm -it -v C:\Users\ww\workspace\TestParamiko\TestParamiko:/var/task lambci/lambda:build-python3.6 bash

This makes the root level of your app visible in the working directory of the container.

Then configuring the aws-sam install with my credentials (your credentials are not copied from the host machine automatically, they are the default that comes with the docker image):

aws config
aws_access_key_id
aws_secret_access_key_id
region

Then you can build package and deploy as normal:

sam build 
sam package --s3-bucket mybucket --template-file .aws-sam/build/template.yaml --output-template-file packaged.yaml
sam deploy --template-file packaged.yaml --stack-name TestParamiko --capabilities CAPABILITY_IAM --region my_region

I put an 'import paramiko' line at the top of the app and ran a test on the console and the lambda runs successfully. I hope this workaround helps anyone with the same problem. - obviously this is not a complete fix as it would be better to have paramiko work as normal in a requirements.txt without the hassle but its a working solution at least! Many thanks for the pointer 'TheSriram'!

@sriram-mv
Copy link
Contributor

Basically you can't have dashes or underscores in your path to your app ( which I happen to have in my code repo path! ) this confused me for a while, but I eventually got the mount to work by copying the root directory of my app to a new directory

Wow, this is interesting! docker and windows path problems. What might help, if there is a functionality added to lamda-builders which is the brain behind sam build to let the user of the cli, if the mount actually worked by running an ls on the current directory, and then an ls inside the docker build container. This would showcase fidelity and assist in debugging mount problems with docker. There have been multiple times where I have seen the docker sharing to appear to work, but fail silently.

It's awesome you were able to figure this out, so once you did this, sam build --use-container has started to work you?

@wes3985
Copy link
Author

wes3985 commented Aug 30, 2019

Yes it does definitely seem like a path issue. Yesterday I was running the above in an interactive container but this morning I've just tested the following as you suggested:

sam build --use-container

And yes this now works perfectly in a path which doesn't contain any dashes or underscores. I agree- this would be a lot easier to debug if there was something to explicitly warn cli users of a potential path issue. Many thanks again for your help!

@Rubyj
Copy link

Rubyj commented Oct 9, 2019

@thesriram Is there any update here? I still have these errors when I try to include a third party library that does not have a whl. Even when I build using sam build --use-container

@Tobi1991
Copy link

@Rubyj I had the same problem and figured out another workaround for the workaround of wes3985. My application folder did not appear in the docker container when I was running 'docker run --rm -it -v <Path_to_my_app>:/var/task lambci/lambda:build-python3.6 bash' (although the path did not contain any dashes or underscores). Therefore I simply used 'git clone <my_repo>' in the docker container. Then you can run 'sam build' in the docker container after configuring your aws credentials.

@Rubyj
Copy link

Rubyj commented Oct 14, 2019

@Tobi1991 Can you give me a run down of the steps you use from the beginning. It's still not fully clear to me. What I am understanding is I need to get the docker image and build that container with a link to my project files. Now you are saying I should clone the repo from inside the image?

@Tobi1991
Copy link

Yes for sure. So the idea of wes3985 was to do 'sam build' inside of the docker container instead of calling 'sam build --use-container' outside of it. Therefore you need your repo (including a template.yaml and the requirements.txt file) in that container. So he used the command 'docker run --rm -it -v C:\Users\ww\workspace\TestParamiko\TestParamiko:/var/task lambci/lambda:build-python3.6 bash' to mount his folder in the container. But this wasnt working for me (just run 'ls' in /var/task when you are in your container to see if its working for you). Therefore I used 'git clone <my_repo>' (inside of the container) to download the files from my remote repository and called 'sam build' after that (after configuring the aws credentials with 'aws configure').

@Rubyj
Copy link

Rubyj commented Oct 15, 2019

@Tobi1991 thank you for the explanation. I am definitely able to build this way after doing a pip install of my wonky packages. Do you it would be possible to then link the container to PyCharm so debugging can be done?

@wes3985
Copy link
Author

wes3985 commented Oct 23, 2019

Good call Tobi1991, I updated docker and the method I used didn't work anymore so another thing you can do if you don't have a git repo (or need to keep your code private) and can't mount your folder in the container is to zip your app up on your local system, upload it to an s3 bucket, then start the docker container, run aws config with your login details, then run ' aws s3 cp s3://my-bucket/myApp.zip myApp.zip', run 'unzip myApp', move into the directory and build/package/deploy as normal.

@djm
Copy link

djm commented Feb 1, 2020

For those that don't want to run the build inside a container:

pip install wheel fixed it for me, without having to use --use-container.

Longer explanation: aws-lambda-builders which is in control of the pip download process looks for linux compatable wheels for each dependency. For those where it only has the sdist (basically raw code) it attempts to build a wheel, and for that it requires the wheel package. If you don't have it installed you'll get this hard to debug error.

@thevikasthakur
Copy link

@djm - fixed my issue

@vallasd
Copy link

vallasd commented May 13, 2020

why does sam require a requirements.txt file for Python3 code. Isnt this file not required for Python 3?

@rojomisin
Copy link

no dashes or underscores in paths? is that reasonable?

@17dagu-irnz
Copy link

@djm and @thevikasthakur, thanks, installing wheel fixed the issue

@jordyvanekelenCB
Copy link

@djm You saved my life thank you

@sriram-mv
Copy link
Contributor

I'm closing this issue and connecting with an issue on the python builder within aws-lambda-builders to improve our error messaging.

aws/aws-lambda-builders#208

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

No branches or pull requests

10 participants