Menu
AWS Greengrass
Developer Guide

How to Configure Local Resource Access Using the AWS Command Line Interface

This feature is available for AWS Greengrass Core v1.3.0 and greater.

In order to use a local resource, you must add a resource definition to the group definition which will be deployed to your Greengrass core device. The group definition must also contain a Lambda function definition in which you grant access permissions for local resources to your Lambda functions. For more information, including requirements and constraints, see Access Local Resources with Lambda Functions.

This tutorial describes the process of creating a local resource and configuring access to it using the AWS Command Line Interface (CLI). It assumes that you've already created a Greengrass group as described in Getting Started with AWS Greengrass.

For a tutorial that uses the AWS Management Console, see How to Configure Local Resource Access Using the AWS Management Console.

Create Local Resources

First, you create a resource definition that specifies the resources to be accessed by using the command CreateResourceDefinition. In this example, we create two resources TestDirectory and TestCamera:

aws greengrass create-resource-definition --cli-input-json '{ "Name": "MyLocalVolumeResource", "InitialVersion": { "Resources": [ { "Id": "data-volume", "Name": "TestDirectory", "ResourceDataContainer": { "LocalVolumeResourceData": { "SourcePath": "/src/LRAtest", "DestinationPath": "/dest/LRAtest", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } }, { "Id": "data-device", "Name": "TestCamera", "ResourceDataContainer": { "LocalDeviceResourceData": { "SourcePath": "/dev/video0", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } } ] } }'

Resources: A list of Resource objects in the Greengrass group. One Greengrass group can have up to 50 resources.

Resource#Id: The unique identifier of the resource. The id is used to refer a resource in the Lambda function configuration. Max length 128 characters. Pattern: [a-zA-Z0-9:_-]+.

Resource#Name: The name of the resource. The resource name is displayed on the Greengrass console. Max length 128 characters. Pattern: [a-zA-Z0-9:_-]+.

LocalVolumeResourceData#SourcePath: The local absolute path of the volume resource on the Greengrass core device. The source path for a volume resource type cannot start with /proc or /sys.

LocalDeviceResourceData#SourcePath: The local absolute path of the device resource. The source path for a device resource can only refer to a character device or block device under /dev.

LocalVolumeResourceData#DestinationPath: The absolute path of the volume resource inside the Lambda environment.

GroupOwnerSetting: Allows you to configure additional group privileges for the Lambda process. This field is optional. For more information, see Group Owner File Access Permission.

GroupOwnerSetting#AutoAddGroupOwner: If true, Greengrass automatically adds the specified Linux OS group owner of the resource to the Lambda process privileges. Thus the Lambda process will have the file access permissions of the added Linux group.

GroupOwnerSetting#GroupOwner: Specifies the name of the Linux OS group whose privileges will be added to the Lambda process. This field is optional.

A resource definition version ARN will be returned by CreateResourceDefinition and should be used when updating a group definition. For example:

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373/versions/a4d9b882-d025-4760-9cfe-9d4fada5390d", "Name": "MyLocalVolumeResource", "LastUpdatedTimestamp": "2017-11-15T01:18:42.153Z", "LatestVersion": "a4d9b882-d025-4760-9cfe-9d4fada5390d", "CreationTimestamp": "2017-11-15T01:18:42.153Z", "Id": "ab14d0b5-116e-4951-a322-9cde24a30373", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373" }

Create the Greengrass Function

After the resources are created, create the Greengrass function using CreateFunctionDefinition and grant the function access to the resource:

aws greengrass create-function-definition --cli-input-json '{ "Name": "MyFunctionDefinition", "InitialVersion": { "Functions": [ { "Id": "greengrassLraTest", "FunctionArn": "arn:aws:lambda:us-west-2:012345678901:function:lraTest:1", "FunctionConfiguration": { "Pinned": false, "MemorySize": 16384, "Timeout": 30, "Environment": { "ResourceAccessPolicies": [ { "ResourceId": "data-volume", "Permission": "rw" }, { "ResourceId": "data-device", "Permission": "ro" } ], "AccessSysfs": true } } } ] } }'

ResourceAccessPolicies: Contains the resourceId and permission which grant the Lambda access to the resource. A Lambda function can have at most 10 resources.

ResourceAccessPolicy#Permission: Specifies which permissions the Lambda has on the resource. The available options are rw (read/write) or ro (readonly).

AccessSysfs: If true, the Lambda process can have read access to the /sys folder on the Greengrass core device. This is used in cases where the Greengrass Lambda needs to read device information from /sys.

Again, a function definition version ARN is returned by CreateFunctionDefinition and should be used in your group definition version.

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad/versions/37f0d50e-ef50-4faf-b125-ade8ed12336e", "Name": "MyFunctionDefinition", "LastUpdatedTimestamp": "2017-11-22T02:28:02.325Z", "LatestVersion": "37f0d50e-ef50-4faf-b125-ade8ed12336e", "CreationTimestamp": "2017-11-22T02:28:02.325Z", "Id": "3c9b1685-634f-4592-8dfd-7ae1183c28ad", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad" }

Add the Lambda Function to the Group

Finally, use CreateGroupVersion to add the function to the group. For example:

aws greengrass create-group-version --group-id "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" \ --resource-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/db6bf40b-29d3-4c4e-9574-21ab7d74316c/versions/31d0010f-e19a-4c4c-8098-68b79906fb87" \ --core-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/cores/adbf3475-f6f3-48e1-84d6-502f02729067/versions/297c419a-9deb-46dd-8ccc-341fc670138b" \ --function-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/d1123830-da38-4c4c-a4b7-e92eec7b6d3e/versions/a2e90400-caae-4ffd-b23a-db1892a33c78" \ --subscription-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/subscriptions/7a8ef3d8-1de3-426c-9554-5b55a32fbcb6/versions/470c858c-7eb3-4abd-9d48-230236bfbf6a"

A new group version is returned:

{ "Arn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/groups/b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5/versions/291917fb-ec54-4895-823e-27b52da25481", "Version": "291917fb-ec54-4895-823e-27b52da25481", "CreationTimestamp": "2017-11-22T01:47:22.487Z", "Id": "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" }

Your Greengrass group now contains the lraTest Lambda function that has access to two resources: TestDirectory and TestCamera.

Here is an example Lambda function, lraTest.py, written in Python, which writes to the local volume resource:

# lraTest.py # Demonstrates a simple use case of local resource access. # This Lambda function writes a file "test" to a volume mounted inside # the Lambda environment under "/dest/LRAtest". Then it reads the file and # publishes the content to the AWS IoT "LRA/test" topic. import sys import greengrasssdk import platform import os import logging # Create a Greengrass Core SDK client. client = greengrasssdk.client('iot-data') volumePath = '/dest/LRAtest' def function_handler(event, context): client.publish(topic='LRA/test', payload='Sent from AWS Greengrass Core.') try: volumeInfo = os.stat(volumePath) client.publish(topic='LRA/test', payload=str(volumeInfo)) with open(volumePath + '/test', 'a') as output: output.write('Successfully write to a file.\n') with open(volumePath + '/test', 'r') as myfile: data = myfile.read() client.publish(topic='LRA/test', payload=data) except Exception as e: logging.error("Experiencing error :{}".format(e)) return

These commands are provided by the Greengrass API to create and manage resource definitions and resource definition versions:

Troubleshooting

  • Q: Why does my Greengrass group deployment fail with an error similar to:

    group config is invalid: ggc_user or [ggc_group root tty] don't have ro permission on the file: /dev/tty0

    A: This error indicates that the Lambda process doesn't have permission to access the specified resource. The solution is to change the file permission of the resource so that Lambda can access it (see Group Owner File Access Permission for more details).

  • Q: When I configure /var/run as a volume resource, why does the Lambda function fail to start with an error message in the runtime.log:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/var/run\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/run\\\" caused \\\"invalid argument\\\"\""

    A: AWS Greengrass core currently doesn't support the configuration of /var, /var/run, and /var/lib as volume resources. One workaround is to first mount /var, /var/run or /var/lib in a different folder and then configure the folder as a volume resource.

  • Q: When I configure /dev/shm as a volume resource with readonly permission, why does the Lambda function fail to start with an error in the runtime.log:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/dev/shm\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/dev/shm\\\" caused \\\"operation not permitted\\\"\""”

    A: /dev/shm can only be configured as read/write. Changing the resource permission to rw will resolve the issue.