acrun

package module
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 36 Imported by: 0

README

acrun

A lightweight deployment tool for AWS Bedrock AgentCore Runtime.

acrun is inspired by lambroll (Lambda) and ecspresso (ECS). It focuses on deployment operations and works with infrastructure managed elsewhere (Terraform/CloudFormation).

Features

  • Simple workflow: init, diff, deploy, invoke
  • Jsonnet/JSON config with useful native functions
  • Infrastructure separation; no scaffolding, just deploy
  • CI/CD friendly with clear exit codes and colored diffs

Install

  • Go: go install github.com/mashiike/acrun/cmd/acrun@latest
  • Binaries: download from GitHub Releases (GoReleaser; darwin/linux/windows, amd64/arm64)

Quick Start

  1. Initialize from an existing runtime
acrun init --agent-runtime-name my-agent --format jsonnet
# writes ./agent_runtime.jsonnet (or json via --format json)
  1. Edit agent_runtime.jsonnet
{
  agentRuntimeName: "my-agent",
  roleArn: "arn:aws:iam::123456789012:role/MyAgentRole",
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: std.native('ecrImageUri')('my-agent', std.native('env')('IMAGE_TAG', 'latest')),
    },
  },
  environmentVariables: { stage: std.native('env')('STAGE', 'dev') },
}
  1. See the diff against remote
acrun diff --exit-code            # exit code 2 when different
acrun diff --ignore '.agentRuntimeVersion'   # jq query to ignore fields
  1. Deploy to an endpoint (non-DEFAULT)
acrun deploy --endpoint-name staging
# creates/updates runtime and the endpoint, then points it to the new version
  1. Invoke for a quick check
echo '{"inputText":"ping"}' | acrun invoke --endpoint-name staging

Commands

  • init: Fetch runtime by name and write agent_runtime.jsonnet or agent_runtime.json.
    • Flags: --agent-runtime-name, --qualifier <endpoint|version>, --format json|jsonnet, --force-overwrite
  • diff: Compare local file with remote runtime (version or endpoint).
    • Flags: --qualifier <endpoint|version> (default: current), --ignore <jq>, --exit-code
  • deploy: Create/update runtime and update or create the specified endpoint.
    • Flags: --endpoint-name <name> (required; cannot be DEFAULT), --dry-run
  • invoke: Call the deployed agent runtime with a payload.
    • Flags: --payload, --content-type, --accept, --endpoint-name (default: current), plus MCP/trace headers (--mcp-proto-version, --mcp-session-id, --runtime-session-id, --runtime-user-id, --baggage, --trace-id, --trace-parent, --trace-state)
  • render: Print normalized config from local file.
    • Flags: --format json|jsonnet
  • delete: Delete the runtime (safe by default).
    • Flags: --force, --dry-run
  • rollback: Point an endpoint to an older version.
    • Flags: --endpoint-name <name> (cannot be DEFAULT), --version <n> (default: current-1), --dry-run

Global flags:

  • --agent-runtime <path>: Path to config file (defaults: agent_runtime.jsonnet or agent_runtime.json in CWD)
  • --tfstate <url|path>: Terraform state location; same as ACRUN_TFSTATE
  • --log-level <debug|info|warn|error> and --log-format <text|json>

Exit codes:

  • diff returns exit code 2 (via --exit-code) when there are differences; other commands use 0/1.

Configuration

acrun reads agent_runtime.jsonnet or agent_runtime.json in the working directory by default. Fields are lowerCamelCase to align with AWS API. You can use Jsonnet to compose per-environment configs.

Jsonnet native functions are provided for convenience. See the detailed section below for usage and examples.

Example: Terraform integration

local tf = std.native('tfstate');
{
  roleArn: tf('aws_iam_role.agent_runtime.arn'),
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: tf('aws_ecr_repository.agent.repository_url') + ':' + std.native('env')('IMAGE_TAG','latest'),
    },
  },
  networkConfiguration: {
    networkMode: 'VPC',
    vpcConfig: {
      subnetIds: [ tf('aws_subnet.private["az-a"].id'), tf('aws_subnet.private["az-b"].id') ],
      securityGroupIds: [ tf('aws_security_group.agent_runtime.id') ],
    },
  },
}

Terraform state locations supported: local files, S3 (s3://...), HTTP/HTTPS, GCS (gs://...), Azure Blob (azurerm://...).

Jsonnet Native Functions

acrun provides several native functions for use in agent_runtime.jsonnet, following Jsonnet's camelCase naming convention:

callerIdentity()

Returns AWS caller identity information from STS GetCallerIdentity API.

  • Returns: Object with account, arn, and userId fields (camelCase).

Example:

local identity = std.native('callerIdentity')();
local accountId = identity.account;

{
  roleArn: 'arn:aws:iam::' + accountId + ':role/MyRole',
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: accountId + '.dkr.ecr.us-west-2.amazonaws.com/my-agent:latest',
    },
  },
  environmentVariables: {
    awsAccountId: accountId,
    awsArn: identity.arn,
    awsUserId: identity.userId,
  },
}
env(name, default)

Returns environment variable value, or default if not set.

Example:

{
  environmentVariables: {
    stage: std.native('env')('STAGE', 'dev'),
  },
}
mustEnv(name)

Returns environment variable value, or raises an error if not set.

Example:

{
  environmentVariables: {
    apiKey: std.native('mustEnv')('API_KEY'),
  },
}
ecrImageUri(repositoryName, imageTag)

Resolves ECR container image URI and verifies the repository exists.

  • Parameters:
    • repositoryName: ECR repository name (e.g., "acrun/sample-mcp")
    • imageTag: Image tag (e.g., "latest", "v1.0.0")
  • Returns: Full ECR image URI string (e.g., "123456789012.dkr.ecr.us-west-2.amazonaws.com/acrun/sample-mcp:latest").
  • Features:
    • Verifies repository exists in ECR using DescribeRepositories
    • Automatically obtains registry ID and repository URI
    • Constructs the complete ECR URI with the specified tag

Example:

{
  agentRuntimeArtifact: {
    containerConfiguration: {
      // Automatically resolves account/region and verifies image exists
      containerUri: std.native('ecrImageUri')('my-agent', 'v1.0.0'),
    },
  },
}

Use with environment variables:

local tag = std.native('env')('IMAGE_TAG', 'latest');
{
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: std.native('ecrImageUri')('my-agent', tag),
    },
  },
}
tfstate(address)

Looks up values from Terraform state file.

  • Prerequisites: Set --tfstate flag or ACRUN_TFSTATE environment variable to point to your Terraform state file (local path or S3 URL).
  • Parameters:
    • address: Terraform resource address (e.g., "aws_iam_role.agent_runtime.arn", "data.aws_subnet.private.id")
  • Returns: The value from the Terraform state at the specified address.

Example:

# Set tfstate location
export ACRUN_TFSTATE="s3://my-bucket/terraform.tfstate"
# or
acrun deploy --tfstate s3://my-bucket/terraform.tfstate
// In agent_runtime.jsonnet
local tfstate = std.native('tfstate');

{
  // Reference IAM role managed by Terraform
  roleArn: tfstate('aws_iam_role.agent_runtime.arn'),

  agentRuntimeArtifact: {
    containerConfiguration: {
      // Reference ECR repository
      containerUri: tfstate('aws_ecr_repository.agent.repository_url') + ':latest',
    },
  },

  networkConfiguration: {
    networkMode: 'VPC',
    vpcConfig: {
      // Reference VPC subnets
      subnetIds: [
        tfstate('aws_subnet.private["az-a"].id'),
        tfstate('aws_subnet.private["az-b"].id'),
      ],
      // Reference security groups
      securityGroupIds: [
        tfstate('aws_security_group.agent_runtime.id'),
      ],
    },
  },
}

Supported state locations:

  • Local file: /path/to/terraform.tfstate
  • S3: s3://bucket/path/to/terraform.tfstate
  • HTTP/HTTPS: https://example.com/terraform.tfstate
  • Google Cloud Storage: gs://bucket/path/to/terraform.tfstate
  • Azure Blob Storage: azurerm://container/path/to/terraform.tfstate

Endpoint Semantics

  • current qualifier resolves the version backing the named endpoint and is used by default in diff/invoke.
  • DEFAULT endpoint is reserved; deploy/rollback against DEFAULT are intentionally blocked. Use your own endpoint names (e.g., dev, staging, prod).

Examples

See _examples/agent/ for a minimal agent project and example configs.

Build from source

go build ./cmd/acrun

Acknowledgements

acrun's design is inspired by:

License

See LICENSE.

Documentation

Overview

Package acrun is a core application logic of acrun command line tool.

Index

Constants

View Source
const (
	AppName             = "acrun"
	DefaultEndpointName = "DEFAULT"
)

Variables

View Source
var (
	DefaultAgentRuntimeFilenames = []string{
		"agent_runtime.json",
		"agent_runtime.jsonnet",
	}
	CurrentEndpointName = "current"
)
View Source
var (
	ErrAgentRuntimeNotFound = errors.New("AgentRuntime not found")
)
View Source
var ErrDiff = &ExitError{Code: 2, Err: nil}
View Source
var Version = "v0.8.1"

Functions

func MakeVM

func MakeVM(ctx context.Context, stsClient STSClient, ecrClient ECRClient, awsCfg aws.Config, globalOpts *GlobalOption) *jsonnet.VM

func ToLowerCamelCase

func ToLowerCamelCase(s string) string

ToLowerCamelCase converts a snake_case string to lowerCamelCase.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

func New

func New(ctx context.Context, opts *GlobalOption) (*App, error)

func NewWithClient

func NewWithClient(
	ctx context.Context,
	opts *GlobalOption,
	awsCfg aws.Config,
	ctrlClient BedrockAgentCoreControlClient,
	client BedrockAgentCoreClient,
	ecrClient ECRClient,
	stsClient STSClient,
) (*App, error)

func (*App) Delete

func (app *App) Delete(ctx context.Context, opt *DeleteOption) error

func (*App) Deploy

func (app *App) Deploy(ctx context.Context, opt *DeployOption) error

func (*App) Diff

func (app *App) Diff(ctx context.Context, opt *DiffOption) error

func (*App) DumpIfVerbose added in v0.6.1

func (app *App) DumpIfVerbose(ctx context.Context, title string, v interface{})

func (*App) ECRImages added in v0.8.0

func (app *App) ECRImages(ctx context.Context, opt *ECRImagesOption) error

ECRImages retrieves the list of ECR image URIs used by the AgentRuntime. This includes images from all endpoints (DEFAULT and aliases) and recent N versions.

func (*App) GetAgentRuntime

func (app *App) GetAgentRuntime(ctx context.Context, name *string, qualifier *string) (*bedrockagentcorecontrol.GetAgentRuntimeOutput, error)

func (*App) GetAgentRuntimeARNByName

func (app *App) GetAgentRuntimeARNByName(ctx context.Context, name string) (string, error)

func (*App) GetAgentRuntimeIDByName

func (app *App) GetAgentRuntimeIDByName(ctx context.Context, name string) (string, error)

func (*App) GetAgentRuntimeVersionByEndpointName

func (app *App) GetAgentRuntimeVersionByEndpointName(ctx context.Context, name string, endpointName string) (string, error)

func (*App) Init

func (app *App) Init(ctx context.Context, opt *InitOption) error

func (*App) Invoke

func (app *App) Invoke(ctx context.Context, opt *InvokeOption) error

func (*App) Render

func (app *App) Render(ctx context.Context, opt *RenderOption) error

func (*App) Rollback

func (app *App) Rollback(ctx context.Context, opt *RollbackOption) error

func (*App) SetOutput

func (app *App) SetOutput(stdout, stderr io.Writer)

type BedrockAgentCoreClient

type BedrockAgentCoreClient interface {
	InvokeAgentRuntime(ctx context.Context, params *bedrockagentcore.InvokeAgentRuntimeInput, optFns ...func(*bedrockagentcore.Options)) (*bedrockagentcore.InvokeAgentRuntimeOutput, error)
}

type BedrockAgentCoreControlClient

type BedrockAgentCoreControlClient interface {
	ListAgentRuntimes(ctx context.Context, params *bedrockagentcorecontrol.ListAgentRuntimesInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.ListAgentRuntimesOutput, error)
	ListAgentRuntimeVersions(ctx context.Context, params *bedrockagentcorecontrol.ListAgentRuntimeVersionsInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.ListAgentRuntimeVersionsOutput, error)
	ListAgentRuntimeEndpoints(ctx context.Context, params *bedrockagentcorecontrol.ListAgentRuntimeEndpointsInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.ListAgentRuntimeEndpointsOutput, error)
	GetAgentRuntime(ctx context.Context, params *bedrockagentcorecontrol.GetAgentRuntimeInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.GetAgentRuntimeOutput, error)
	GetAgentRuntimeEndpoint(ctx context.Context, params *bedrockagentcorecontrol.GetAgentRuntimeEndpointInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.GetAgentRuntimeEndpointOutput, error)
	CreateAgentRuntime(ctx context.Context, params *bedrockagentcorecontrol.CreateAgentRuntimeInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.CreateAgentRuntimeOutput, error)
	CreateAgentRuntimeEndpoint(ctx context.Context, params *bedrockagentcorecontrol.CreateAgentRuntimeEndpointInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.CreateAgentRuntimeEndpointOutput, error)
	UpdateAgentRuntime(ctx context.Context, params *bedrockagentcorecontrol.UpdateAgentRuntimeInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.UpdateAgentRuntimeOutput, error)
	UpdateAgentRuntimeEndpoint(ctx context.Context, params *bedrockagentcorecontrol.UpdateAgentRuntimeEndpointInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.UpdateAgentRuntimeEndpointOutput, error)
	DeleteAgentRuntime(ctx context.Context, params *bedrockagentcorecontrol.DeleteAgentRuntimeInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.DeleteAgentRuntimeOutput, error)
	DeleteAgentRuntimeEndpoint(ctx context.Context, params *bedrockagentcorecontrol.DeleteAgentRuntimeEndpointInput, optFns ...func(*bedrockagentcorecontrol.Options)) (*bedrockagentcorecontrol.DeleteAgentRuntimeEndpointOutput, error)
}

type CLI

type CLI struct {
	GlobalOption
	Color     bool   `help:"enable colored output" default:"true" env:"ACRUN_COLOR" negatable:"" json:"color,omitempty"`
	LogLevel  string `help:"Log level" default:"info" enum:"debug,info,warn,error"`
	LogFormat string `help:"Log format(text,json)" default:"text" enum:"text,json"`

	Init      InitOption      `cmd:"" help:"Initialize acrun configuration."`
	Invoke    InvokeOption    `cmd:"" help:"Invoke the agent."`
	Diff      DiffOption      `cmd:"" help:"Diff the local and remote agent runtime."`
	Deploy    DeployOption    `cmd:"" help:"Deploy the agent runtime."`
	Render    RenderOption    `cmd:"" help:"Render the agent runtime configuration."`
	Delete    DeleteOption    `cmd:"" help:"Delete the agent runtime."`
	Rollback  RollbackOption  `cmd:"" help:"Rollback the agent runtime to a specific version."`
	ECRImages ECRImagesOption `cmd:"ecr-images" help:"List ECR image URIs used by the agent runtime."`
	Version   struct{}        `cmd:"" help:"Show version."`
}

func (*CLI) Run

func (c *CLI) Run(ctx context.Context) error

type DeleteOption

type DeleteOption struct {
	DryRun          bool          `name:"dry-run" help:"dry run" default:"false"`
	Force           bool          `name:"force" help:"force delete without confirmation" default:"false"`
	WaitDuration    time.Duration `name:"wait-duration" help:"maximum duration to wait until the agent runtime is ready" default:"30m"`
	PollingInterval time.Duration `name:"polling-interval" help:"polling interval to check the agent runtime status" default:"5s"`
}

type DeployOption

type DeployOption struct {
	DryRun          bool          `name:"dry-run" help:"dry run" default:"false"`
	EndpointName    *string       `name:"endpoint-name" help:"the endpoint name to deploy. if not specified, use the default endpoint."`
	WaitDuration    time.Duration `name:"wait-duration" help:"maximum duration to wait until the agent runtime is ready" default:"30m"`
	PollingInterval time.Duration `name:"polling-interval" help:"polling interval to check the agent runtime status" default:"5s"`
}

type DiffOption

type DiffOption struct {
	Qualifier *string `help:"the qualifier to compare; allow endpoint name or version number"`
	Ignore    string  `help:"ignore diff by jq query" default:""`
	ExitCode  bool    `help:"exit with code 2 if there are differences" default:"false"`
}

type ECRClient

type ECRClient interface {
	DescribeRepositories(ctx context.Context, params *ecr.DescribeRepositoriesInput, optFns ...func(*ecr.Options)) (*ecr.DescribeRepositoriesOutput, error)
}

type ECRImagesOption added in v0.8.0

type ECRImagesOption struct {
	Versions int `help:"Number of recent versions to include." default:"5"`
}

ECRImagesOption represents the options for the ecr-images command.

type ExitError

type ExitError struct {
	Code int
	Err  error
}

func (*ExitError) Error

func (e *ExitError) Error() string

func (*ExitError) Unwrap

func (e *ExitError) Unwrap() error

type GlobalOption

type GlobalOption struct {
	AgentRuntime string            `help:"Agent runtime file path"  json:"agent_runtime,omitempty"`
	TFState      string            `name:"tfstate" help:"Terraform state file URL (s3://... or local path)" env:"ACRUN_TFSTATE" json:"tfstate,omitempty"`
	ExtStr       map[string]string `help:"Set external string variable for Jsonnet VM" env:"ACRUN_EXTSTR" json:"ext_strs,omitempty"`
	ExtCode      map[string]string `help:"Set external code variable for Jsonnet VM" env:"ACRUN_EXTCODE" json:"ext_codes,omitempty"`
	Verbose      bool              `name:"verbose" short:"v" help:"enable verbose logging" default:"false" json:"verbose,omitempty"`
	Region       string            `name:"region" help:"AWS Region" env:"AWS_REGION,ACRUN_REGION" json:"region,omitempty"`
	Profile      string            `name:"profile" help:"AWS CLI profile name" env:"AWS_PROFILE,ACRUN_PROFILE" json:"profile,omitempty"`
}

type InitOption

type InitOption struct {
	AgentRuntimeName string  `help:"AgentRuntime name." required:"true"`
	Qualifier        *string `help:"the qualifier to initialize. if not specified, use the latest version." default:""`
	Format           string  `help:"Output format. json or jsonnet" default:"jsonnet" enum:"json,jsonnet"`
	ForceOverwrite   bool    `help:"Overwrite existing files without prompting" default:"false"`
}

type InvokeOption

type InvokeOption struct {
	Payload      *string `help:"payload to invoke. if not specified, read from STDIN"`
	ContentType  *string `help:"The MIME type of the input data in the payload"`
	Accept       *string `help:"Accept header for the response"`
	EndpointName *string `help:"the endpoint name to invoke. if not specified, use the CURRENT endpoint."`

	MCPProtocolVersion *string `name:"mcp-proto-version" help:"The version of the MCP protocol being used."`
	MCPSessionID       *string `name:"mcp-session-id" help:"The identifier of the MCP session."`
	RuntimeSessionID   *string `name:"runtime-session-id" help:"The identifier of the runtime session."`
	RuntimeUserID      *string `name:"runtime-user-id" help:"The user identifier for the runtime session."`
	Baggage            *string `help:"Baggage for distributed tracing"`
	TraceID            *string `name:"trace-id" help:"The trace identifier for request tracking."`
	TraceParent        *string `name:"trace-parent" help:"The parent span identifier for distributed tracing."`
	TraceState         *string `name:"trace-state" help:"The state information for distributed tracing."`
}

type RenderOption

type RenderOption struct {
	Format string `help:"output format (json, jsonnet)" default:"json" enum:"json,jsonnet"`
}

type RollbackOption

type RollbackOption struct {
	DryRun       bool    `name:"dry-run" help:"dry run" default:"false"`
	EndpointName *string `name:"endpoint-name" help:"the endpoint name to rollback. if not specified, use the default endpoint."`
	Version      *string `name:"version" help:"the version to rollback to. if not specified, rollback to current version - 1"`
}

type STSClient

type STSClient interface {
	GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error)
}

type Waiter added in v0.6.1

type Waiter struct {
	MaxDuration   time.Duration
	CheckInterval time.Duration
	LogInterval   time.Duration
	LogMessage    string
	LogAttributes []any
	Checker       func(context.Context) ([]any, bool, error)
}

func (*Waiter) Wait added in v0.6.1

func (w *Waiter) Wait(ctx context.Context) error

Directories

Path Synopsis
cmd
acrun command
codegen command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL