AWS IOT greengrass v2 Token exchange service

0

I have a greengrass component which pulls a docker image from ECR and has the token exchange service as a hard dependency. The pull succeeds, and we are able to get the image. Once the image is on the device, we manually create a container off it. The problem is that when I try to call the AWS APIs it does not work, it errors out with the following error message:

2021-03-12 18:13:52,496 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): localhost:44721
2021-03-12 18:13:52,498 - MainThread - urllib3.connectionpool - DEBUG - http://localhost:44721 "GET /2016-11-01/credentialprovider/ HTTP/1.1" 403 0
2021-03-12 18:13:52,498 - MainThread - botocore.utils - DEBUG - Received error when attempting to retrieve container metadata: Error retrieving metadata: Received non 200 response (403) from ECS metadata:

We print out the value of the 5 environment variables listed in the docker IPC manual:
AWS_REGION
SVCUID
AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT
AWS_CONTAINER_AUTHORIZATION_TOKEN
AWS_CONTAINER_CREDENTIALS_FULL_URI

And inject them into the docker container when starting it manually (using -e variable and setting --net=host). If I try to execute docker run as part of the lifecycle script in greengrass, it works, and we can call the AWS APIs. I know that we can curl using the X.509 certs, and it will work in principle, but is there a way to get it to work with out running the curl commands (similar to how it works when invoking docker run in the lifecycle script)?

asked 3 years ago700 views
4 Answers
0

Hi ankitm123,

Thanks for using Greengrass V2, in order to help resolve the query could you provide a bit more information? When you say you are trying to call AWS APIs, is it from within the container that you run and you need TokenExchangeService to get credentials for those APIs? If you're setting the AWS_CONTAINER_CREDENTIALS_FULL_URI env then ideally that should work. Could you post your recipe so we can better understand the problem?

Thanks,
Shagupta

AWS
answered 3 years ago
0

shagupta-aws wrote:
Hi ankitm123,

Thanks for using Greengrass V2, in order to help resolve the query could you provide a bit more information? When you say you are trying to call AWS APIs, is it from within the container that you run and you need TokenExchangeService to get credentials for those APIs? If you're setting the AWS_CONTAINER_CREDENTIALS_FULL_URI env then ideally that should work. Could you post your recipe so we can better understand the problem?

Thanks,
Shagupta

Hi Shagupta,

Yes, I am running aws sts get-caller-identity --debug from inside the container.
This is the recipe file (not sure how to better format the recipe yaml in this post):
{
"RecipeFormatVersion": "2020-01-25",
"ComponentName": "com.companytest.testDocker",
"ComponentVersion": "1.0.4",
"ComponentType": "aws.greengrass.generic",
"ComponentDescription": "A component that runs a Docker container.",
"ComponentPublisher": "Amazon",
"ComponentConfiguration": {
"DefaultConfiguration": {
"accessControl": {
"aws.greengrass.ipc.pubsub": {
"mount-solved-test:pubsub:1": {
"policyDescription": "Allows access to publish to test/topic.",
"operations": [
""
],
"resources": [
"
"
]
}
}
}
}
},
"ComponentDependencies": {
"aws.greengrass.TokenExchangeService": {
"VersionRequirement": ">=2.0.0 <3.0.0",
"DependencyType": "HARD"
}
},
"Manifests": [
{
"Platform": {
"os": "linux"
},
"Lifecycle": {
"Run": {
"Script": "export DOCKER_CONFIG=$HOME/.docker\n docker pull XXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/docker-test:latest"
}
},
"Artifacts": []
}
],
"Lifecycle": {}
}

So this recipe pulls the image into the IOT device, and then we start the container manually (not the ggc_user but another system user) using:
docker run -e AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT=/greengrass/v2/ipc.socket -e AWS_CONTAINER_CREDENTIALS_FULL_URI=http://localhost:44721/2016-11-01/credentialprovider/ -e AWS_REGION=us-east-2 --net=host -v /greengrass/v2:/greengrass/v2 --privileged <the pulled docker image> sleep 5000

Then I exec into that container and install aws cli, and run aws sts-get-caller --debug
I did set the token and SVCID manually inside the container as environment variables, but that did not help (Setting them or not setting them does not make a difference afaict)

Edited by: ankitm123 on Mar 12, 2021 11:25 AM

Edited by: ankitm123 on Mar 12, 2021 11:26 AM

Edited by: ankitm123 on Mar 12, 2021 11:39 AM

answered 3 years ago
0

Thank you for the details. Since you are running the container and using AWS CLI manually and not as part of your component's lifecycle, you might need another environment variable i.e. AWS_CONTAINER_AUTHORIZATION_TOKEN. You can find out the value for this the way you did for other env variables you set. Could you try that and let us know if it works?

As you noted earlier, it worked out of the box if you run the container as part of the component lifecycle, and your docker run command doesn't include this env variable, that leads me to think that this env variable might be the missing link, because it is required by the AWS SDK and hence automatically set by the Greengrass Nucleus for component processes. But for using Token Exchange Service manually, the env variable should also be manually set.

Please let us know if that works. If it still doesn't we will try to dig deeper. We have not tested this type of manual usage because it's outside the scope of Greengrass. I think considering that and many other benefits, it will be better to actually run the container as part of the component lifecycle instead of running manually, unless you have a specific use case that stops you from doing that.

Thanks,
Shagupta

Edited by: shagupta-aws on Mar 12, 2021 1:04 PM

AWS
answered 3 years ago
0

shagupta-aws wrote:
Thank you for the details. Since you are running the container and using AWS CLI manually and not as part of your component's lifecycle, you might need another environment variable i.e. AWS_CONTAINER_AUTHORIZATION_TOKEN. You can find out the value for this the way you did for other env variables you set. Could you try that and let us know if it works?

As you noted earlier, it worked out of the box if you run the container as part of the component lifecycle, and your docker run command doesn't include this env variable, that leads me to think that this env variable might be the missing link, because it is required by the AWS SDK and hence automatically set by the Greengrass Nucleus for component processes. But for using Token Exchange Service manually, the env variable should also be manually set.

Please let us know if that works. If it still doesn't we will try to dig deeper. We have not tested this type of manual usage because it's outside the scope of Greengrass. I think considering that and many other benefits, it will be better to actually run the container as part of the component lifecycle instead of running manually, unless you have a specific use case that stops you from doing that.

Thanks,
Shagupta

Edited by: shagupta-aws on Mar 12, 2021 1:04 PM

Yes passing the token as an environment variable manually to the docker container made it work! Thanks!

answered 3 years ago

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