diff --git a/CLAUDE.md b/CLAUDE.md index da02738..22d2804 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ The CLI uses the Cobra framework with commands organized under `internal/cli/`: ### AWS Integration The CLI heavily integrates with AWS services: -- CloudFormation - Stack management and output retrieval +- Resource Groups Tagging API - Resource discovery - SSM - Instance connections - CloudWatch Logs - Log streaming - AppRunner - Service health checks @@ -46,7 +46,7 @@ The CLI heavily integrates with AWS services: - AWS credentials via standard AWS SDK configuration (profiles, environment variables, IAM roles) ### Key Patterns -1. Commands retrieve stack outputs from CloudFormation to get resource ARNs +1. Commands discover resources via Resource Groups Tagging API to get resource ARNs 2. Context propagation for AWS config through command execution 3. Structured error handling with context-aware messages 4. Real-time log streaming with optional watch mode diff --git a/README.md b/README.md index 17b75dd..f325a49 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,23 @@ jobs: run: roc lint .github/runs-on.yml ``` +## Resource Discovery + +The CLI discovers RunsOn resources using the AWS Resource Groups Tagging API (RGTA): + +1. **Primary**: `runs-on-stack-name` tag (all new CF/TF deployments) +2. **Fallback**: Dynamic discovery via AppRunner service tags (older stacks) + +Resources are identified by their `runs-on-resource` tag (Terraform) or ARN pattern matching (fallback): + +| Resource | Tag Value | CF Fallback | +|----------|-----------|-------------| +| AppRunner Service | `apprunner-service` | ARN pattern | +| Config S3 Bucket | `config-bucket` | `runs-on/purpose=config` tag or name contains `-config` | +| EC2 Log Group | `ec2-log-group` | Name contains `{stack}/ec2/instances` | + +Tags are automatically applied when deploying RunsOn via Terraform/OpenTofu or CloudFormation. + ## Core Commands ### `roc connect` diff --git a/go.mod b/go.mod index 2c9e160..95d0c61 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/aws/aws-sdk-go-v2 v1.38.3 github.com/aws/aws-sdk-go-v2/config v1.31.6 github.com/aws/aws-sdk-go-v2/service/apprunner v1.38.3 - github.com/aws/aws-sdk-go-v2/service/cloudformation v1.66.0 github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.57.2 github.com/aws/aws-sdk-go-v2/service/ec2 v1.251.0 github.com/aws/aws-sdk-go-v2/service/fis v1.37.1 diff --git a/go.sum b/go.sum index d58da58..b503b0c 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,6 @@ github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.6 h1:R0tNFJqfjHL3900cqhXuwQ+1K4G0 github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.6/go.mod h1:y/7sDdu+aJvPtGXr4xYosdpq9a6T9Z0jkXfugmti0rI= github.com/aws/aws-sdk-go-v2/service/apprunner v1.38.3 h1:h6HKdn8kmz/bpDAM8eIX/Nu0oSoewQH4l1hiRukqYoE= github.com/aws/aws-sdk-go-v2/service/apprunner v1.38.3/go.mod h1:17A21aZwtJWcU346UqC5h5iynSNesczxeYQn5TX39lU= -github.com/aws/aws-sdk-go-v2/service/cloudformation v1.66.0 h1:zDKnCvsZ21fO1oCx1Dj+QofcU2MABkM9gdb1278an+Y= -github.com/aws/aws-sdk-go-v2/service/cloudformation v1.66.0/go.mod h1:wkKFqGoZf9Asi1eKuWbz7SEx0RtCq4+drWwHKzizP9o= github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.57.2 h1:TSNLZXt7ipIV+Q+GZAQ8dUxYUDsMX2/Atrn/YuPF3zI= github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.57.2/go.mod h1:mSt0uBAxUj2dnagbjc7p+Jh68SSwgDTNzMKUjchDiOY= github.com/aws/aws-sdk-go-v2/service/ec2 v1.251.0 h1:hGHSNZDTFnhLGUpRkQORM8uBY9R/FOkxCkuUUJBEOQ4= diff --git a/internal/cli/logs.go b/internal/cli/logs.go index 3405f21..eb24fc8 100644 --- a/internal/cli/logs.go +++ b/internal/cli/logs.go @@ -15,7 +15,6 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/cloudformation" "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/s3" @@ -41,7 +40,6 @@ type LogFetcher struct { cfg aws.Config cwl *cloudwatchlogs.Client s3 *s3.Client - cfn *cloudformation.Client ec2 *ec2.Client stackName string outputs *StackOutputs @@ -60,7 +58,6 @@ func NewLogFetcher(config *RunsOnConfig) *LogFetcher { cfg: config.AWSConfig, cwl: cloudwatchlogs.NewFromConfig(config.AWSConfig), s3: s3.NewFromConfig(config.AWSConfig), - cfn: cloudformation.NewFromConfig(config.AWSConfig), ec2: ec2.NewFromConfig(config.AWSConfig), stackName: config.StackName, outputs: &StackOutputs{ @@ -664,7 +661,7 @@ func NewStackLogsCmd(stack *Stack) *cobra.Command { Use: "logs", Short: "Stream all RunsOn application logs from CloudWatch", Long: `Stream all RunsOn application logs from the CloudWatch log group. - + This command streams all application logs from the RunsOn service, not filtered by specific jobs. Use this to monitor overall service activity and troubleshoot system-wide issues.`, diff --git a/internal/cli/root.go b/internal/cli/root.go index f2bc2a1..c747bfb 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -38,7 +38,7 @@ func NewRootCmd(stack *Stack) *cobra.Command { } } - cmd.PersistentFlags().String("stack", defaultStack, "CloudFormation stack name") + cmd.PersistentFlags().String("stack", defaultStack, "Stack name") cmd.PersistentFlags().BoolVar(&noColor, "no-color", false, "Disable color output") cmd.AddCommand( diff --git a/internal/cli/stack.go b/internal/cli/stack.go index 6bf6ed1..25443ed 100644 --- a/internal/cli/stack.go +++ b/internal/cli/stack.go @@ -53,12 +53,12 @@ func NewStackCmd(stack *Stack) *cobra.Command { cmd := &cobra.Command{ Use: "stack", Short: "RunsOn stack management commands", - Long: `Commands for managing and troubleshooting your RunsOn CloudFormation stack. + Long: `Commands for managing and troubleshooting your RunsOn stack. -These commands operate on your deployed RunsOn CloudFormation stack to help you +These commands operate on your deployed RunsOn stack to help you manage, monitor, and troubleshoot your RunsOn infrastructure. -The stack name can be specified using the --stack flag or by setting the +The stack name can be specified using the --stack flag or by setting the RUNS_ON_STACK_NAME environment variable (defaults to "runs-on").`, }