Introduction to Greengrass Components - 101
Published: 2023-05-09 16:46:05


## Introduction

[AWS IoT Greengrass](https://docs.aws.amazon.com/greengrass/v2/developerguide/what-is-iot-greengrass.html) is an open source Internet of Things (IoT) edge runtime and cloud service that helps you build, deploy and manage IoT applications on your fleet of edge devices. In Greengrass parlance, IoT applications running on a Greengrass device is called a Greengrass component. Greengrass users can develop components and deploy on their edge devices for various uses such as acting locally on data generated at the edge, filtering and aggregating data generated at edge and running predictions based on machine learning models at the edge. In this blog, we will dive deeper into Greengrass components. 
![AWS IoT Greengrass](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vbgngnk2ez9m718loo7.png)
## What are Greengrass Components ? 

AWS IoT Greengrass components are software modules that you deploy to Greengrass core devices. In more simpler words, all business logic that you want to run as code on an edge device has to be modeled as a component which Greengrass can understand, install and run. Components can represent your custom applications or AWS provided applications, runtime installers, libraries, or any code that you would run on a device. 

## Types of Components: 

There are primarily three types of components present in the Greengrass world: 

1. **Greengrass provided Components** - These are components provided and maintained by AWS Greengrass to be used by customers at no charge. There are several features which AWS has identified as common across our customers’ use cases and prebuilt them. You can use these components independently without even building your custom components or you can add these components as a dependency (more on this later) on your own component and it will automatically be deployed to the edge device with your custom component. Some examples of public components are: (a) [stream manager](https://docs.aws.amazon.com/greengrass/v2/developerguide/stream-manager-component.html) - stream high volume data from edge device to the AWS cloud; (b) [log manager](https://docs.aws.amazon.com/greengrass/v2/developerguide/log-manager-component.html) - collects and uploads logs from your edge device to CloudWatch. For complete list of pre-built components by AWS Greengrass, please refer [this link](https://docs.aws.amazon.com/greengrass/v2/developerguide/public-components.html).
2. **Community provided Components -** These are components that are built by developer community on Github under the umbrella of Amazon open source software. In order to use these components you can pull the source code, make modifications as per your use case, create your own private components and deploy to your edge devices. You can find these components through [Greengrass Software Catalog](https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-software-catalog.html). You can also learn about maintenance and development of these components in the [Github contributing guidelines.](https://github.com/aws-greengrass/aws-greengrass-software-catalog/blob/main/CONTRIBUTING.md)
3. **Private Components** - These are the components that you develop and manage. These components are private to your AWS account i.e. no other user will have read/write access to your components. You write the software of your IoT application, for ex - an application to collect data from a temperature sensor and adjust the room’s thermostat based on certain conditions. You need to follow a series of steps (to be discussed in later blogs) to model your IoT application as a Greengrass component which can be deployed to your edge device.

The mental model to build is components are modular software applications that run on an edge device. Often our customers tend to use a combination of three types of components to build a complete IoT solution. 

## Core Concepts of a Component:

Let’s dive into the core concepts of a component and later understand how the concepts connect with each other to create an Greengrass Component. Each component has two major parts - an Artifact and a Recipe: 

1. **Artifact** - Artifact is the business logic of your component. It can include scripts, compiled code, static resources, and any other files that a component consumes. You develop the application code you want to run on a Greengrass core device. Greengrass supports three locations where you can store the artifact(s) of your component: 
    1. S3 Bucket - This S3 bucket belongs in your personal account.
    2. Lambda - You can import AWS Lambda functions as artifact of your components that run on AWS IoT Greengrass core devices. In this case you don’t need to upload your application code to S3. Scenarios in which you may choose to run lambda functions for instance if  you have application code in AWS Lambda functions that you want to deploy to core devices. Don’t worry about the details, more details on containerization of lambda functions will follow in our future blog series. 
    3. Docker container - You can store your artifacts in locations like ECR if you want to run your application code in a Docker container on your edge device. More details about running a Docker container on Greengrass core device will follow in our future blog series. Examples of locations where your docker images can be stored: 
        1. Public and private image repositories in Amazon Elastic Container Registry (Amazon ECR)
        2. Public Docker Hub repository
        3. Public Docker Trusted Registry
        4. S3 bucket (in your personal account)

Example of how an artifact is specified in a recipe: 
```
"Artifacts": [
     {
        "URI": "s3://{COMPONENT_NAME}/{COMPONENT_VERSION}/HelloWorld.zip",
        "Unarchive": "ZIP"
     }
]
```
1. **Recipe -** Component recipe is a single YAML or JSON configuration file for the component author to define runtime characteristics of your component so that Greengrass can execute and manage lifecycle of your component. You can understand recipe as a set of instructions which is consumed by Greengrass to interact with your application code, for ex - interpret how to download artifacts and install your component on the edge device, pull your component dependencies, decide if the component artifacts needs to be unzipped or installed as-is etc. More details around recipe will be dived deep in later blogs.

## Create Your First Component:

In the section above, you learned about the core concepts of a component i.e. an artifact and a recipe. Now, let’s see how the two concepts can be used in a series of steps to create your first private component. 

### Step1: Create your private component’s artifact, in this case a simple Hello-World python code

```
# hello-world.py

import sys
import datetime

message = f"Hello, {sys.argv[1]}! Current time: {str(datetime.datetime.now())}."
message += " Greetings from your first Greengrass component."
# Print the message to stdout.
print(message)

# Append the message to the log file.
with open('/tmp/RatchetWorkshop_HelloWorld.log', 'a') as f:
    print(message, file=f)
```

### Step2: Upload your artifact to an AWS S3 bucket

Let’s use S3 as our choice to store the artifact as an example in this blog (other sources to follow soon in later blogs). You can use an existing S3 bucket or create a new one. For simplicity let’s create a new S3 bucket: 

***Setup AWS CLI on your machine:***

```
# Follow link based on your operating system:
" https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html "
```

***Create a Bucket:***

```
$ aws s3 mb s3://greengrass-component-artifacts-blog --region us-east-1
```

_*Output:*_

```
make_bucket: greengrass-component-artifacts-blog
```

***Upload the Artifact:***

```
$ aws s3 cp ~/hello-world.py s3://greengrass-component-artifacts-blog/artifacts/com.example.HelloWorld/1.0.0/hello_world.py --region us-east-1
```

_*Output:*_

```
./hello-world.py to s3://greengrass-component-artifacts-blog/artifacts/com.example.HelloWorld/1.0.0/hello_world.py
```

### Step3: Create the recipe file for your private component: 

Firstly, from the step above let’s use the S3 URI in which your artifact is uploaded which we’ll use in the recipe: 

```
"Artifacts": [
  {
    "URI": "s3://greengrass-component-artifacts-blog/artifacts/com.example.HelloWorld/1.0.0/hello_world.py"
  }
]
```

Now, let’s create the recipe file for your custom component: 

```
# Path: ~/GreengrassComponents/com.example.HelloWorld-1.0.0.json

{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.HelloWorld",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "My first AWS IoT Greengrass component.",
  "ComponentPublisher": "Your Organization Identifier",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "Message": "world"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "Run": "python3 -u {artifacts:path}/hello_world.py '{configuration:/Message}'"
      },
   "Artifacts": [
        {
          "URI": "s3://greengrass-component-artifacts-blog/artifacts/com.example.HelloWorld/1.0.0/hello_world.py"
        }
      ]
    }
  ]
}
```

Don’t worry about the data structure of the recipe file and what do different attributes mean. We’ll dive into each of them in our future blogs. 

### Step4: Create a new private component version in AWS Greengrass-V2

Now, that you have created the artifact and the recipe for your private component let’s create the first private component using [CreateComponentVersion](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateComponentVersion.html) API of Greengrass-V2: 

```
$ aws greengrassv2 create-component-version --inline-recipe fileb://GreengrassComponents/com.example.HelloWorld-1.0.0.json --region us-east-1
```

_*Output:*_

```
{
    "arn": "arn:aws:greengrass:us-east-1:223644865437:components:com.example.HelloWorld:versions:1.0.0",
    "componentName": "com.example.HelloWorld",
    "componentVersion": "1.0.0",
    "creationTimestamp": "2023-05-03T20:51:17.517000-07:00",
    "status": {
        "componentState": "REQUESTED",
        "message": "NONE",
        "errors": {},
        "vendorGuidance": "ACTIVE",
        "vendorGuidanceMessage": "NONE"
    }
} 
```

As you can see in the output above which shows ARN (Amazon Resource Name) of your private component, the component has been created. The component when first created is in a `REQUESTED` because the Greengrass service verifies the component and if it succeeds then it changes state to `DEPLOYABLE` which you can verify by calling [DescribeComponent](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_DescribeComponent.html) API: 

```
$ aws greengrassv2 describe-component --arn "arn:aws:greengrass:us-east-1:223644865437:components:com.example.HelloWorld:versions:1.0.0" --region us-east-1
```

_*Output:*_

```
{
    "arn": "arn:aws:greengrass:us-east-1:223644865437:components:com.example.HelloWorld:versions:1.0.0",
    "componentName": "com.example.HelloWorld",
    "componentVersion": "1.0.0",
    "creationTimestamp": "2023-05-03T20:51:17.517000-07:00",
    "publisher": "Your Organization Identifier",
    "description": "My first AWS IoT Greengrass component.",
    "status": {
        "componentState": "DEPLOYABLE",
        "message": "NONE",
        "errors": {},
        "vendorGuidance": "ACTIVE",
        "vendorGuidanceMessage": "NONE"
    },
    "platforms": [
        {
            "attributes": {
                "os": "linux"
            }
        }
    ],
    "tags": {}
}
```

**Congratulations !!** You just made your first private component in AWS Greengrass-V2. You can now [deploy this component to your Greengrass core device](https://docs.aws.amazon.com/greengrass/v2/developerguide/manage-deployments.html) and see it in action.

## Conclusion: 

In this blog, we talked about components primarily focussing on describing “what” they are. We learnt about different types of components available in AWS IoT Greengrass-V2 and how to build a mental model to picture a software application as a component. I’m pretty sure that you’ll be curious to know - what are those different fields in the recipe, what do they mean, how will I deploy my component to a core device, what is a Greengrass core device etc. Well, those are all great questions and you don’t need to worry - our upcoming blogs in this series will dive into each of these topics and answer all your questions. 
Till then, happy coding. Please reach out if you have any questions or need help with your development, we're always happy to help.