Deploy to Greengrass
This page covers deploying a GGCommons component to AWS IoT Greengrass v2, where it runs on the
GREENGRASS platform and talks to the Nucleus over Greengrass IPC (the IPC transport). You
build and package the component with the GDK (Greengrass Development Kit), then either deploy it
locally with greengrass-cli or push it to a fleet from the cloud.
Every component the ggcommons CLI scaffolds already ships the two files the GDK needs —
gdk-config.json (build + publish settings) and recipe.yaml (the component recipe) — so you
rarely write either by hand.
Prerequisites
Section titled “Prerequisites”- A scaffolded component (
ggcommons create-componentwithGREENGRASSamong its target platforms — the default). See the Quickstart. - The GDK CLI (
gdk) installed and on yourPATH, plus AWS credentials with permission to upload artifacts to S3 and register component versions. Confirm withggcommons doctor, which reports whethergdkandawsare present. - An S3 bucket for published artifacts. The CLI writes the bucket/region you pass at scaffold
time into
gdk-config.json(--bucket/--region, defaulting togreengrass-component-artifacts-us-east-1inus-east-1). - A Greengrass v2 core device running the Nucleus, plus the Greengrass CLI component
(
greengrass-cli) installed on it if you want to deploy locally.
How a component runs under Greengrass
Section titled “How a component runs under Greengrass”On the GREENGRASS platform the runtime resolves two defaults from the platform profile, so the
launch command is short:
- Transport defaults to
IPC— you do not pass--transport. (IPCis valid only onGREENGRASS; selecting it on another platform fails fast.) - Config source defaults to
GG_CONFIG— the component reads its configuration from the Greengrass deployment rather than a local file.
The generated recipe.yaml wires this into the component’s Run lifecycle for you. The exact launch
line differs per language (and the artifact layout differs with it):
The recipe sets the CONFIG environment variable from the deployment configuration and launches
the shaded JAR on the GREENGRASS platform. Config source is left to the profile default
(GG_CONFIG), so no -c flag is passed:
# recipe.yaml -> Manifests[0].Lifecycle.Run (tokens resolved to example values)java -cp {artifacts:path}/MyComponent-1.0.0.jar com.example.MyComponent --platform GREENGRASS# with Setenv CONFIG: "{configuration:/ComponentConfig}"The recipe activates the per-component venv (created in the install lifecycle) and runs main.py
on the GREENGRASS platform, relying on the GG_CONFIG profile default (no -c flag):
# recipe.yaml -> Manifests[0].Lifecycle.Run (tokens resolved to example values)python3 -u {artifacts:decompressedPath}/MyComponent/main.py --platform GREENGRASSThe recipe chmod +x’s the binary in the Install lifecycle, then runs it. The Rust recipe
passes -c GG_CONFIG explicitly (the result is identical to relying on the profile default):
# recipe.yaml -> Manifests[0].Lifecycle.Run (tokens resolved to example values){artifacts:path}/MyComponent --platform GREENGRASS -c GG_CONFIGThe recipe runs the prebuilt JS bundle (no on-device install step). Like Rust, it passes
-c GG_CONFIG explicitly:
# recipe.yaml -> Manifests[0].Lifecycle.Run (tokens resolved to example values)node {artifacts:decompressedPath}/MyComponent/dist/main.js --platform GREENGRASS -c GG_CONFIGBuild and publish with the GDK
Section titled “Build and publish with the GDK”gdk component build runs the per-language build declared in gdk-config.json and stages the
artifact + recipe; gdk component publish uploads the artifact to your S3 bucket and registers a new
component version in your account. These two commands are the same for every language — run them from
the generated component directory:
cd MyComponentgdk component buildgdk component publishcd MyComponentgdk component buildgdk component publishPer-language packaging notes
Section titled “Per-language packaging notes”What gdk component build actually does — and the artifact it produces — is driven by the
build_system in gdk-config.json:
build_system: "maven" — the GDK runs Maven to produce a shaded, self-contained JAR
(target/MyComponent-1.0.0.jar). The recipe’s Manifests.Platform.os is all. The recipe also
declares a HARD dependency on the Token Exchange Service (TES) so the component can obtain AWS
credentials on-device.
# gdk-config.json -> component.<name>.build.build_system = "maven"gdk component buildbuild_system: "zip" — the GDK produces a ZIP artifact (Unarchive: ZIP). The recipe’s
install lifecycle creates a per-component venv under the work dir and pip installs
requirements.txt. Manifests.Platform.os is all, and the recipe declares a HARD TES
dependency.
# gdk-config.json -> component.<name>.build.build_system = "zip"gdk component buildbuild_system: "custom" → custom_build_command: ["bash", "build.sh"]. build.sh compiles the
release binary with the greengrass cargo feature (Greengrass IPC). The recipe’s
Manifests.Platform.os is linux and its Install lifecycle chmod +x’s the binary.
gdk component build# The greengrass feature compiles a C-FFI SDK and only builds on Linux (needs libclang).# Build on a Linux host/WSL, or cross-compile:GGCOMMONS_TARGET=x86_64-unknown-linux-gnu gdk component buildbuild_system: "custom" → custom_build_command: ["bash", "build.sh"]. build.sh runs
npm install + npm run build (tsc) and stages a ZIP bundling dist/ + node_modules/ +
package.json, so there is no on-device install step. The recipe’s Manifests.Platform.os is
linux.
# gdk-config.json -> component.<name>.build.build_system = "custom" (bash build.sh)gdk component buildWhat the generated recipe declares
Section titled “What the generated recipe declares”The scaffolded recipe.yaml is a complete Greengrass v2 component recipe. The parts you are most
likely to touch:
ComponentConfiguration.DefaultConfiguration.ComponentConfig— the component’s default config (logging, heartbeat,metricEmission,tags, and thecomponentinstances block). This is the same schema theGG_CONFIGsource reads; override any of it from a deployment.accessControl— IPC authorization policies the component needs:aws.greengrass.ipc.pubsub(local pub/sub),aws.greengrass.ipc.mqttproxy(publish/subscribe to IoT Core), andaws.greengrass.ShadowManager(thing shadows). The defaults grant*; tighten theresourcesto the topics/shadows your component actually uses.Manifests— the artifact URI (rewritten bygdk component publish) and theRunlifecycle shown above.osisallfor Java/Python andlinuxfor Rust/TypeScript.
gdk-config.json holds the build system, the publish bucket/region, and the NEXT_PATCH
version. Edit the recipe and re-run gdk component build to pick up changes.
Deploy locally with greengrass-cli
Section titled “Deploy locally with greengrass-cli”For a development core device you can deploy straight from the device without going through the
cloud, using the Greengrass CLI. After building, copy the recipe and artifact onto the core, then
create a local deployment that merges the component (<Comp>=<ver> names the component and
version):
# Run on the core device. Point --recipeDir / --artifactDir at the recipe and the built artifact.greengrass-cli deployment create \ --recipeDir ./recipes \ --artifactDir ./artifacts \ --merge "com.example.MyComponent=1.0.0"
# Tear the component down again:greengrass-cli deployment create --remove "com.example.MyComponent"# Run on the core device (greengrass-cli typically lives under C:\greengrass\v2\bin).greengrass-cli deployment create ` --recipeDir .\recipes ` --artifactDir .\artifacts ` --merge "com.example.MyComponent=1.0.0"
# Tear the component down again:greengrass-cli deployment create --remove "com.example.MyComponent"Deploy to devices from the cloud
Section titled “Deploy to devices from the cloud”Once a version is published, deploy it to a thing or thing group via the cloud. The ggcommons CLI
wraps the whole flow — gdk component build, gdk component publish, then
aws greengrassv2 create-deployment:
ggcommons deploy -p . -t arn:aws:iot:us-east-1:123456789012:thinggroup/edge-fleetggcommons deploy -p . -t arn:aws:iot:us-east-1:123456789012:thinggroup/edge-fleetVerify the deployment
Section titled “Verify the deployment”- On the core device, check component status with the Greengrass CLI:
greengrass-cli component list(and watch the Nucleus logs under/greengrass/v2/logs/). - Subscribe to
heartbeat/+/+to confirm the component is alive and emitting heartbeats — over IPC these surface on the local pub/sub bus (and on IoT Core if the heartbeat target is configured for it). The topic uses the{ThingName}and{ComponentName}template variables.