acrun

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 37 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), --keep-versions <n>, --dry-run
    • --keep-versions <n> deletes older runtime versions after the endpoint is updated, keeping the n newest. Versions referenced by any endpoint (LiveVersion or TargetVersion, including DEFAULT) are always kept, so a version an endpoint was rolled back to is never deleted. The default 0 keeps every version. Requires the bedrock-agentcore:DeleteAgentRuntime permission. Pruning is best-effort: any failure there (missing permissions, throttling, a version that cannot be deleted) is logged as a warning and never fails the deploy. Note that n bounds how far rollback can go back.
  • 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.9.0"

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

Deploy creates or updates the agent runtime described by the configuration file, then points the endpoint named by opt.EndpointName at the resulting version, creating that endpoint if it does not exist yet.

Deploying to the DEFAULT endpoint is rejected. Old versions are pruned afterwards as described on DeployOption; the prune is skipped when the runtime was just created. Pruning is best-effort: failures there are logged as warnings and never fail the deploy.

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."`
	KeepVersions    int           `` /* 181-byte string literal not displayed */
	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"`
}

DeployOption holds the flags of the deploy command.

When KeepVersions is greater than zero, versions older than the newest KeepVersions are deleted after the endpoint has been updated. Versions that any endpoint references through its live or target version are always kept, so a version an endpoint was rolled back to is never deleted.

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
⌂ 换网址