Skip to content

AWS IoT Greengrass Installation

The following guide provides the steps to install AWS IoT Greengrass V2 on an Eurotech IoT Gateway. The process will install AWS IoT Greengrass V2 with automatic resource provisioning. Please refer to the AWS IoT Greengrass V2 Documentation for altenative installation methods.

Prepare the Eurotech Gateway

Create the default system user and group that runs components on your device.

sudo useradd --system --create-home ggc_user
sudo groupadd --system ggc_group
sudo usermod -aG docker idt_ggc_user
sudo visudo
root ALL=(ALL:ALL) ALL

Provide AWS credentials to the device

Provide your AWS credentials to your device so that the installer can provision the required AWS resources. Run the following commands to provide the credentials to the AWS IoT Greengrass Core software.

export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Download AWS IoT Greengrass Core software

Download the AWS IoT Greengrass Core Installer and prepare for the installation.

sudo mkdir -p /opt/aws/
cd /opt/aws/
sudo curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip --output greengrass-nucleus-latest.zip
sudo unzip greengrass-nucleus-latest.zip -d GreengrassInstaller
sudo rm greengrass-nucleus-latest.zip
sudo java -jar ./GreengrassInstaller/lib/Greengrass.jar --version

Install AWS IoT Greengrass Core software

Run the AWS IoT Greengrass Core installer. Replace argument values in your command as follows. - region. The AWS Region in which to find or create resources (e.g. us-east-1) - EurotechIoTGatewayGreengrassCore. The name of the AWS IoT thing for your Greengrass core device. If the thing doesn't exist, the installer creates it. - MyGreengrassCoreGroup. The name of AWS IoT thing group for your Greengrass core device. If the thing group doesn't exist, the installer creates it and adds the thing to it. - GreengrassV2IoTThingPolicy. The name of the AWS IoT policy that allows the Greengrass core devices to communicate with AWS IoT and AWS IoT Greengrass. If the AWS IoT policy doesn't exist, the installer creates a permissive AWS IoT policy with this name. - GreengrassV2TokenExchangeRole. The name of the IAM role that allows the Greengrass core device to get temporary AWS credentials. If the role doesn't exist, the installer creates it and creates and attaches a policy named GreengrassV2TokenExchangeRoleAccess. - GreengrassCoreTokenExchangeRoleAlias. The alias to the IAM role that allows the Greengrass core device to get temporary credentials later. If the role alias doesn't exist, the installer creates it and points it to the IAM role that you specify.

The following command sets up the AWS IoT Greengrass Core software as a system service that runs when this device boots. The system service name is greengrass. For more information on the GreengrassInstaller arguments, please refer to the AWS IoT Greengrass Documentation.

cd /opt/aws/
sudo -E java -Droot="/opt/aws/greengrass/v2" -Dlog.store=FILE \
  -jar ./GreengrassInstaller/lib/Greengrass.jar \
  --aws-region region \
  --thing-name EurotechIoTGatewayGreengrassCore \
  --thing-group-name MyGreengrassCoreGroup \
  --thing-policy-name GreengrassV2IoTThingPolicy \
  --tes-role-name GreengrassV2TokenExchangeRole \
  --tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
  --component-default-user ggc_user:ggc_group \
  --deploy-dev-tools \
  --provision true \
  --setup-system-service true

Configure AWS IoT Greengrass nucleus

Run the following command to check the status of the Greengrass system service. sudo systemctl status greengrass.service

To enable the nucleus to start when the device boots. sudo systemctl enable greengrass.service

To stop the nucleus from starting when the device boots. sudo systemctl disable greengrass.service

To start the AWS IoT Greengrass Core software. sudo systemctl start greengrass.service

To stop the AWS IoT Greengrass Core software. sudo systemctl stop greengrass.service

To view the log messages of the AWS IoT Greengrass Core software. sudo journalctl -u greengrass.service -f

If AWS IoT Greengrass Core service should not find the java executable in the path, please add a link to java under /usr/bin. For example, add a symbolic link like the following: sudo ln -s /usr/java/bin/java /usr/bin/java

Eurotech recommends to use the following configuration of JVM options for teh AWS IoT Greengrass nucleus configuration:

./bin/greengrass-cli component details --name aws.greengrass.Nucleus

nano aws_greengrass_Nucleus.json
{
  "aws.greengrass.Nucleus": {
    "MERGE": {
      "jvmOptions": "-Xmx64m -XX:+UseSerialGC -XX:TieredStopAtLevel=1"
    }
  }
}

sudo mkdir artifacts
sudo mkdir recipes
sudo ./bin/greengrass-cli deployment create \
  --recipeDir recipes \
  --artifactDir artifacts \
  --merge "aws.greengrass.Nucleus=2.5.3" \
  --update-config aws_greengrass_Nucleus.json

./bin/greengrass-cli deployment status -i 80b76202-1982-4de2-a4e9-2b142ede8154
./bin/greengrass-cli component details --name aws.greengrass.Nucleus

For other AWS IoT Greengrass configuration options please refer to the AWS IoT Greengrass documentation.

AWS IoT Greengrass Installation with Hardware Security Integration

Create the AWS IoT Thing

Get the AWS IoT data endpoint for your AWS account.

aws iot describe-endpoint --endpoint-type iot:Data-ATS
{
    "endpointAddress": "a1rm1gogglx99n-ats.iot.us-east-1.amazonaws.com"
}

Get the AWS IoT credentials endpoint for your AWS account.

aws iot describe-endpoint --endpoint-type iot:CredentialProvider
{
    "endpointAddress": "c3s9r3bwgw6exe.credentials.iot.us-east-1.amazonaws.com"
}

Create an AWS IoT thing

aws iot create-thing --thing-name REGATE-10-14-GreengrassCoreHSM
{
    "thingName": "REGATE-10-14-GreengrassCoreHSM",
    "thingArn": "arn:aws:iot:us-east-1:332696098873:thing/REGATE-10-14-GreengrassCoreHSM",
    "thingId": "dc732ab7-6b3f-44d9-8575-21d9fc1732d0"
}

Add the AWS IoT thing to a thing group.

aws iot add-thing-to-thing-group --thing-name REGATE-10-14-GreengrassCoreHSM --thing-group-name EurotechGreengrassCoreGroup

Create the certificate from a private key in an HSM

On the device, create the certificate from a private key in an HSM. Eurotech gateways use a TPM 2.0 hardware security module. The AWS IoT Greengrass certificate will be loaded in the TPM Owner Hierarchy.

Initialize TPM 2.0 Storage Root Key

If the TPM has not been initialized, create a Storage Root Key (SRK) and persist it with the following command.

sudo mkdir -p /opt/aws/tpm2/
sudo chmod 777 /opt/aws/tpm2/
cd /opt/aws/tpm2/
tpm2_createprimary -C o -G rsa -g sha256 \
    -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt" \
    -c srk.ctx
tpm2_evictcontrol -C o -c srk.ctx 0x81000001

Create a private key for the AWS IoT Thing

Create a private key for the AWS IoT Thing under the Storage Root Key. We will call that key Local Device ID (LDevID) and we will make it persistent at 0x81000002.

tpm2_create -C 0x81000001 \
    -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|sign|decrypt|noda" \
    -G rsa2048:null:null -g sha256 \
    -u ldevid.pub -r ldevid.priv 
tpm2_load -C 0x81000001 -u ldevid.pub -r ldevid.priv -c ldevid.ctx
tpm2_evictcontrol -C o -c ldevid.ctx 0x81000002

Create a CSR and a Certificate for the AWS IoT Thing

Create a certificate signing request (CSR) from the private key. AWS IoT uses this CSR to create a thing certificate for the private key that you generated in the HSM.

openssl req -new -engine tpm2tss -keyform engine -key 0x81000002 \
    -config openssl-devids.conf -reqexts ldevid \
    -out ldevid.csr

Copy the CSR from the device to your development computer.

scp ldevid.csr host-ip-address:~/ldevid.csr 

On the host, use the CSR file to create and download the certificate for the AWS IoT thing to your development computer.

mkdir greengrass-v2-certs
aws iot create-certificate-from-csr --set-as-active --certificate-signing-request=file://ldevid.csr --certificate-pem-outfile greengrass-v2-certs/ldevid.pem.crt
{
    "certificateArn": "arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d",
    "certificateId": "162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d",
    "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIVAJHaEri69bhONajM7gb3g8Kenm6qMA0GCSqGSIb3DQEB\nCwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\nIEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0yMjAyMTUyMTEx\nNTJaFw00OTEyMzEyMzU5NTlaMEAxETAPBgNVBAoMCEV1cm90ZWNoMRgwFgYDVQQD\nDA9SRUdBVEUtMTAtMTQtMzYxETAPBgNVBAUTCDAxMDIwMzA0MIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1iJp5z0d7eiwFZf+J/epxX6xeDr7iZ9eUwS\n65fwBRGaTLNMjD6NdV1zH/8ClWrYN/gnKosjzji6AHb2cyDj9b8tnQCEakJfLSh6\nwpID0wdJyM7RHqqQw4ZNKn2JDXqam2XGZCZBt3UDeOKxTm5mS2A4LgmkNpoEdqof\nNJJmNYsckowN8j/SIKD9b5FouI4//qF1zUmmzeidqS2HFno0FZnrdIcUZdJfTLYf\n6zn1g3hCFkpa1xE2k3vidrP36HStbjzcj9PNaFzbTdwpUx+7gzsxl2kC8AoZygoO\n0g1kN6GrCYPSHTASAWbQXQJzJw/RSnjlIj3QvnB2ce10XH6+DQIDAQABo2AwXjAf\nBgNVHSMEGDAWgBTSuW1XP6mpLBsdpakikv5OXfq7XzAdBgNVHQ4EFgQUZsEqsvf9\nfiov7or3EnzTYvoHOnEwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJ\nKoZIhvcNAQELBQADggEBAAOGtPIu3C1UIwUYenfWyGJkPXlAIWc/C2enbQ17LH9J\nvvMptXumiPUsuk4gSbfgI639YkD70nkvUO2uFvwtFC4We//jmx2E+Oe4xJQ457Yo\nrn/Yftt5RTcyFq9ggsXhylps4ae0WbR7bYOg+JBOeaoi9R0hhf4k3qB44kMz1Hc1\nE+JcFbwPqh+80oz7cd6V5oaKz1rT5Lle7R8FTUMuC1wXMHMb5n4QjFgSvnzKdko3\nAvfdOTB2dicIJ2qKeMsu0COchZFVNSzxGA2KKuyKtarg/S+A4xn3dc6bHQ9LlHXQ\niUAt+TLCcO72BcErkYYEST8sje3CLur2a++n4uoWLCo=\n-----END CERTIFICATE-----\n"
}

Copy the certificate to the device.

scp greengrass-v2-certs/ldevid.pem.crt guest@device-ip:/opt/aws/tpm2/

Attach the certificate to the AWS IoT thing.

aws iot attach-thing-principal --thing-name REGATE-10-14-GreengrassCoreHSM --principal arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d

Create and attach an AWS IoT policy that defines the AWS IoT permissions for your Greengrass core device.

nano greengrass-v2-iot-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive",
        "iot:Connect",
        "greengrass:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
aws iot create-policy --policy-name EthGreengrassV2IoTThingPolicy --policy-document file://greengrass-v2-iot-policy.json
{
    "policyName": "EthGreengrassV2IoTThingPolicy",
    "policyArn": "arn:aws:iot:us-east-1:332696098873:policy/EthGreengrassV2IoTThingPolicy",
    "policyDocument": "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Publish\",\n        \"iot:Subscribe\",\n        \"iot:Receive\",\n        \"iot:Connect\",\n        \"greengrass:*\"\n      ],\n      \"Resource\": [\n        \"*\"\n      ]\n    }\n  ]\n}\n",
    "policyVersionId": "1"
}

Attach the AWS IoT policy to the AWS IoT thing's certificate.

aws iot attach-policy --policy-name EthGreengrassV2IoTThingPolicy --target arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d

Create a token exchange IAM role

nano device-role-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "credentials.iot.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

aws iam create-role --role-name EthGreengrassV2TokenExchangeRole --assume-role-policy-document file://device-role-trust-policy.json
{
    "Role": {
        "Path": "/",
        "RoleName": "EthGreengrassV2TokenExchangeRole",
        "RoleId": "AROAU25R3TA4QZW5HN3HB",
        "Arn": "arn:aws:iam::332696098873:role/EthGreengrassV2TokenExchangeRole",
        "CreateDate": "2022-02-15T21:44:59+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "credentials.iot.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

Create a file that contains the access policy document that the token exchange role requires.

nano device-role-access-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:DescribeCertificate",
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams",
        "s3:GetBucketLocation"
      ],
      "Resource": "*"
    }
  ]
}

aws iam create-policy --policy-name EthGreengrassV2TokenExchangeRoleAccess --policy-document file://device-role-access-policy.json
{
    "Policy": {
        "PolicyName": "EthGreengrassV2TokenExchangeRoleAccess",
        "PolicyId": "ANPAU25R3TA4UJAMA4QXI",
        "Arn": "arn:aws:iam::332696098873:policy/EthGreengrassV2TokenExchangeRoleAccess",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2022-02-15T21:46:42+00:00",
        "UpdateDate": "2022-02-15T21:46:42+00:00"
    }
}

Attach the IAM policy to the token exchange role.

aws iam attach-role-policy --role-name EthGreengrassV2TokenExchangeRole --policy-arn arn:aws:iam::332696098873:policy/EthGreengrassV2TokenExchangeRoleAccess

Create an AWS IoT role alias that points to the token exchange role.

aws iot create-role-alias --role-alias EthGreengrassCoreTokenExchangeRoleAlias --role-arn arn:aws:iam::332696098873:role/EthGreengrassV2TokenExchangeRole
{
    "roleAlias": "EthGreengrassCoreTokenExchangeRoleAlias",
    "roleAliasArn": "arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias"
}

Create and attach an AWS IoT policy that allows your Greengrass core device to use the role alias to assume the token exchange role.

nano greengrass-v2-iot-role-alias-policy.json
{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:AssumeRoleWithCertificate",
      "Resource": "arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias"
    }
  ]
}

aws iot create-policy --policy-name EthGreengrassCoreTokenExchangeRoleAliasPolicy --policy-document file://greengrass-v2-iot-role-alias-policy.json
{
    "policyName": "EthGreengrassCoreTokenExchangeRoleAliasPolicy",
    "policyArn": "arn:aws:iot:us-east-1:332696098873:policy/EthGreengrassCoreTokenExchangeRoleAliasPolicy",
    "policyDocument": "{\n  \"Version\":\"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"iot:AssumeRoleWithCertificate\",\n      \"Resource\": \"arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias\"\n    }\n  ]\n}\n",
    "policyVersionId": "1"
}

Attach the AWS IoT policy to the AWS IoT thing's certificate.

aws iot attach-policy --policy-name EthGreengrassCoreTokenExchangeRoleAliasPolicy --target arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d

Import the AWS IoT Thing Certificate into the HSM

If not already done, initialize a PKCS11 store in the TPM 2. A store creates a primary object under the owner hierarchy and each primary object is mapped to a slot. Make sure to define the /etc/tpm2_pkcs11/ directory to store the PKCS11 supporting information for the tpm2_tools, tpm2_ptool, and the libpcks11 library.

> sudo mkdir /etc/tpm2_pkcs11/
> tpm2_ptool init --primary-handle 0x81000001
action: Added
id: 1

After creating a slot, now one needs to create a token. This is accomplished with the addtoken command for tpm2-ptool, using the primary object ID from previous step. A token is created and a unique name called a label is provided. The label is used in subsequent commands to reference the token.

tpm2_ptool addtoken --pid '1' --label 'aws' --userpin '1234' --sopin '1234' 

Now link private key for the AWS IoT Thing to PKCS#11 'aws' token with ldevid key-label. Then, install the AWS IoT Thing device certificate in the same slot with the same key-label.

cd /opt/aws/tpm2/
tpm2_ptool link --label='aws' --userpin='1234' --key-label="ldevid" ldevid.pub ldevid.priv
tpm2_ptool addcert --label='aws' --key-label='ldevid' ldevid.pem.crt
tpm2_ptool listobjects --label 'aws'

Install the AWS IoT Greengrass Core software

Install the AWS IoT Greengrass Core software.

Download the Amazon root certificate authority (CA) certificate. AWS IoT certificates are associated with Amazon's root CA certificate by default.

sudo mkdir -p /opt/aws/greengrass/v2
sudo chmod 755 /opt/aws/greengrass
sudo curl -o /opt/aws/greengrass/v2/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem

Download the AWS IoT Greengrass Core software.

curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip
unzip greengrass-nucleus-latest.zip -d GreengrassInstaller && rm greengrass-nucleus-latest.zip
java -jar ./GreengrassInstaller/lib/Greengrass.jar --version

Download the PKCS#11 provider plugin to a file named aws.greengrass.crypto.Pkcs11Provider.jar.

curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/Pkcs11Provider/aws.greengrass.crypto.Pkcs11Provider-latest.jar > GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar

Create a configuration file named config.yaml to provide to the installer.

nano GreengrassInstaller/config.yaml
---
system:
  certificateFilePath: "pkcs11:object=ldevid;type=cert"
  privateKeyPath: "pkcs11:object=ldevid;type=private"
  rootCaPath: "/opt/aws/greengrass/v2/AmazonRootCA1.pem"
  rootpath: "/opt/aws/greengrass/v2"
  thingName: "REGATE-10-14-GreengrassCoreHSM"
services:
  aws.greengrass.Nucleus:
    componentType: "NUCLEUS"
    version: "2.5.3"
    configuration:
      awsRegion: "us-east-1"
      iotRoleAlias: "EthGreengrassCoreTokenExchangeRoleAlias"
      iotDataEndpoint: "a1rm1gogglx99n-ats.iot.us-east-1.amazonaws.com"
      iotCredEndpoint: "c3s9r3bwgw6exe.credentials.iot.us-east-1.amazonaws.com"
  aws.greengrass.crypto.Pkcs11Provider:
    configuration:
      name: "tpm2_pkcs11"
      library: "/usr/lib/pkcs11/libtpm2_pkcs11.so.0.0.0"
      slot: 2
      userPin: 1234

Run the installer.

sudo -E java -Droot="/opt/aws/greengrass/v2" -Dlog.store=FILE \
  -jar ./GreengrassInstaller/lib/Greengrass.jar \
  --trusted-plugin ./GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar \
  --init-config ./GreengrassInstaller/config.yaml \
  --component-default-user ggc_user:ggc_group \
  --setup-system-service true

If needed, the Greengrass configuration can be updated as follows.

sudo systemctl stop greengrass.service
sudo nano /opt/aws/greengrass/v2/config/effectiveConfig.yaml
sudo java -Droot="/opt/aws/greengrass/v2" \
  -jar /opt/aws/greengrass/v2/alts/current/distro/lib/Greengrass.jar \
  --start false \
  --init-config /opt/aws/greengrass/v2/config/effectiveConfig.yaml
sudo systemctl start greengrass.service
sudo journalctl -u greengrass.service -f
sudo tail -100f /opt/aws/greengrass/v2/