Skip to main content

Set up your environment

This guide helps you prepare your environment to work with nullplatform. Once your setup is ready, you can move on to creating your custom scopes.

Before you start

Make sure you have the following tools installed:

  • Docker
  • Access to a Kubernetes cluster (or a distribution such as k3s or minikube).

Get started

  1. Install the nullplatform CLI.

    curl https://cli.nullplatform.com/install.sh | sh
  2. Export your access token.

    You can retrieve it using our Chrome extension.

    export NP_TOKEN=your_access_token
  3. Create an API key and assign the required roles.

    • From the platform, navigate to Platform settings > API keys, and click + New API key.
    • Select the account resource where the API key's roles will be assigned.
    • Select the required roles: agent, developer, ops, secops and secrets-reader.
    • Save your API key.

Note: If you prefer, you can create your API key using our CLI or API. See our docs for request examples and details.

  1. Export the API key in a new terminal to avoid environment variable conflicts.

    export NP_API_KEY=your_api_key_here
  2. Export the NP_ACTION_CONTEXT as an environment variable.

    export NP_ACTION_CONTEXT=action_context_variable
    JSON example of the environment variable
    {
    "notification": {
    "action": "scope:create",
    "id": "a1b2c3d4-e5f6-7a89-b012-3456789abcde",
    "name": "create-scope",
    "slug": "create-scope",
    "status": "pending",
    "created_at": "2025-01-14T20:13:12.761Z",
    "updated_at": "2025-01-14T20:13:16.557Z",
    "parameters": {
    "scope_id": 1111
    },
    "results": {},
    "type": "create",
    "specification": {
    "id": "9876fedc-ba09-4cde-8f01-23456789abcd",
    "slug": "publish-message"
    },
    "service": {
    "id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789",
    "slug": "pub-sub-service-1",
    "attributes": {
    "repository": "my-repository/pubsub-module"
    },
    "specification": {
    "id": "123abc45-6789-def0-1234-56789abcdef0",
    "slug": "publisher-subscriber"
    },
    "dimensions": {
    "country": "ARG",
    "environment": "development"
    }
    },
    "link": null,
    "tags": {
    "organization_id": "1",
    "organization": "my-organization",
    "account_id": "2",
    "account": "my-account",
    "namespace_id": "3",
    "namespace": "my-namespace",
    "application_id": "4",
    "application": "my-application"
    },
    "entity_nrn": "organization=1:account=2:namespace=3:application=4"
    }
    }

Set up the nullplatfrom agent

Install and run the nullplatform np-agent, which connects your environment to the nullplatform backend to execute tasks.

Install it in your machine or in a Docker container.

  • Install the nullplatform agent.

    curl https://cli.nullplatform.com/agent/install.sh
  • Or install the agent in a Docker container.

    To use the agent in a containerized setup, create a Dockerfile using the configuration below:

    FROM alpine

    ## Agent docker
    RUN apk add --no-cache curl ca-certificates bash openssl aws-cli gettext gomplate jq yq

    RUN curl https://cli.nullplatform.com/install.sh | sh
    RUN curl https://cli.nullplatform.com/agent/install.sh | sh
    RUN mkdir -p /root/.np

    ADD run_agent.sh /app/run_agent.sh
    ENV PATH=$PATH:/root/.local/bin
    entrypoint ["/app/run_agent.sh"]
    Agent startup script
    #!/bin/bash

    # Variable to store the child process PID
    NP_AGENT_PID=""

    # Log function
    log() {
    echo "[$(date -Iseconds)] $1"
    }

    # Signal handling function
    cleanup() {
    local signal=$1
    log "Received signal: $signal"

    if [ -n "$NP_AGENT_PID" ] && kill -0 $NP_AGENT_PID 2>/dev/null; then
    log "Sending SIGTERM to np-agent process $NP_AGENT_PID"
    kill -15 $NP_AGENT_PID

    # Wait for the child process to terminate with a timeout
    log "Waiting for np-agent process to terminate..."

    # Give the process time to clean up (similar to preStop hook time)
    local timeout=25 # Less than the 30s termination grace period
    local end_time=$(($(date +%s) + $timeout))

    while kill -0 $NP_AGENT_PID 2>/dev/null && [ $(date +%s) -lt $end_time ]; do
    log "Process $NP_AGENT_PID still running, waiting..."
    sleep 1
    done

    if kill -0 $NP_AGENT_PID 2>/dev/null; then
    log "Process $NP_AGENT_PID did not terminate gracefully within timeout"
    log "Sending SIGKILL to process $NP_AGENT_PID"
    kill -9 $NP_AGENT_PID
    else
    log "Process $NP_AGENT_PID terminated gracefully"
    fi
    else
    log "No running np-agent process found"
    fi

    log "Cleanup complete, exiting with appropriate status"
    # Exit with appropriate status
    if [ "$signal" = "EXIT" ]; then
    exit 0
    else
    # Exit with signal + 128 which is a common convention
    exit $(( 128 + $(kill -l $signal) ))
    fi
    }

    # Trap signals
    trap 'cleanup TERM' TERM
    trap 'cleanup INT' INT
    trap 'cleanup HUP' HUP
    trap 'cleanup QUIT' QUIT
    trap 'cleanup USR1' USR1
    trap 'cleanup USR2' USR2
    trap 'cleanup EXIT' EXIT

    # Start np-agent process
    log "Starting np-agent process..."
    /root/.local/bin/np-agent \
    --apikey=$NP_API_KEY \
    --runtime=host \
    --tags=$TAGS \
    --command-executor-env=NP_API_KEY="\"$NP_API_KEY\"" \
    --command-executor-command-folders /root/.np/services \
    --command-executor-debug \
    --webserver-enabled &

    # Store the PID of np-agent
    NP_AGENT_PID=$!
    log "np-agent process started with PID: $NP_AGENT_PID"

    # Wait for the np-agent process to complete
    # Using 'wait' allows the script to receive signals
    wait $NP_AGENT_PID
    EXIT_STATUS=$?

    log "np-agent process exited with status: $EXIT_STATUS"
    exit $EXIT_STATUS

What's next?

Now that your environment is ready, you're all set to move on and create your custom scope.