bcp (Blob Copy) provides SCP-like functionality for copying files
to and from EC2 instances through S3 and AWS Systems Manager (SSM).
- Bidirectional Transfer: Copy files both TO and FROM EC2 instances
- Resource Discovery: List available S3 buckets and SSM-managed EC2 instances
- Robust Error Handling: Retry logic with exponential backoff for transient failures
- Input Validation: Comprehensive validation of paths, instance IDs, and bucket names
- Structured Logging: Configurable logging with multiple levels (debug, info, warn, error)
- Configuration File Support: YAML-based configuration with sensible defaults
- Progress Reporting: Clear progress messages during uploads and downloads
- Automatic Cleanup: S3 objects are automatically cleaned up after successful transfers
Copy TO remote instance:
bcp [local_source] [ssm_instance_id:remote_destination] --bucket BUCKET_NAMECopy FROM remote instance:
bcp [ssm_instance_id:remote_source] [local_destination] --bucket BUCKET_NAMEArguments:
local_source: Local directory or file path to upload (when copying TO remote)local_destination: Local directory or file path to download to (when copying FROM remote)ssm_instance_id:remote_path: SSM instance ID and remote path (format:i-xxxxxxxxx:/path/to/file)
Discover available AWS resources before copying:
# List all S3 buckets
bcp list buckets
# List SSM-managed EC2 instances
bcp list instances
# List all EC2 instances (including non-SSM)
bcp list instances --all
# List instances in a specific region
bcp list instances --region us-west-2-b, --bucket: S3 bucket name for transfer (required if not set in config)-c, --config: Path to config file (default:$HOME/.bcp/config.yaml)-v, --verbose: Enable verbose output (debug level)-q, --quiet: Suppress all output except errors-h, --help: Display help information
-
Local Machine:
- Go 1.20+ (for building from source)
- AWS CLI installed and configured with appropriate credentials
- IAM permissions for S3 and SSM
-
Remote Instance:
- AWS CLI installed
- SSM Agent running
- IAM instance profile with S3 read permissions
-
Clone the repository:
git clone https://github.com/cowdogmoo/bcp.git cd bcp -
Build the project:
go build -o bcp
-
(Optional) Move to PATH:
sudo mv bcp /usr/local/bin/
Create a configuration file at $HOME/.bcp/config.yaml:
---
log:
format: text # text, json, or color
level: info # debug, info, warn, error
aws:
region: us-east-1
profile: default
bucket: my-default-bucket # Optional: default S3 bucket
transfer:
max_retries: 3 # Maximum retry attempts
retry_delay: 2 # Base delay in seconds (exponential backoff)See cmd/config/config.yaml for a complete example.
Enable autocomplete for bucket names, instance IDs, and common paths:
Bash:
# One-time setup (Linux)
bcp completion bash | sudo tee /etc/bash_completion.d/bcp
# One-time setup (macOS with Homebrew)
bcp completion bash > $(brew --prefix)/etc/bash_completion.d/bcp
# Or source directly in current shell
source <(bcp completion bash)Zsh:
# Enable completion system (if not already enabled)
echo "autoload -U compinit; compinit" >> ~/.zshrc
# One-time setup
bcp completion zsh > "${fpath[1]}/_bcp"
# Restart shell or reload
source ~/.zshrcFish:
# One-time setup
bcp completion fish > ~/.config/fish/completions/bcp.fish
# Reload completions
source ~/.config/fish/completions/bcp.fishCompletion Features:
bcp --bucket <TAB>- Autocomplete S3 bucket namesbcp file.txt <TAB>- Autocomplete SSM instance IDsbcp file.txt i-xxx:<TAB>- Suggest common destination paths (/tmp/, /home/ec2-user/, /opt/, etc.)
# List available S3 buckets
bcp list buckets
# List SSM-managed instances (shows instance ID, status, platform, IP, and name)
bcp list instances
# List all instances including non-SSM ones
bcp list instances --all
# List instances in a specific region
bcp list instances --region us-east-1# Copy a directory TO an EC2 instance
bcp ./my-files i-1234567890abcdef0:/home/ec2-user/files --bucket my-bucket
# Copy a single file TO an EC2 instance
bcp ~/app/binary i-1234567890abcdef0:/usr/local/bin/myapp --bucket my-bucket
# Copy a directory FROM an EC2 instance
bcp i-1234567890abcdef0:/home/ec2-user/files ./my-files --bucket my-bucket
# Copy a single file FROM an EC2 instance
bcp i-1234567890abcdef0:/var/log/app.log ./logs/app.log --bucket my-bucket# Enable debug logging to see detailed progress
bcp ./my-files i-1234567890abcdef0:/home/ec2-user/files --bucket my-bucket --verbose# Use a custom config file
bcp ./my-files i-1234567890abcdef0:/home/ec2-user/files --config ./my-config.yaml# Only show errors
bcp ./my-files i-1234567890abcdef0:/home/ec2-user/files --bucket my-bucket --quiet# 1. Discover available buckets and instances
bcp list buckets
bcp list instances
# 2. Copy files TO remote using discovered resources
bcp ./deployment i-1234567890abcdef0:/opt/app --bucket my-bucket
# 3. Copy files FROM remote
bcp i-1234567890abcdef0:/opt/app/logs ./logs --bucket my-bucket# Run all tests
go test ./...
# Run tests with coverage
go test ./... -cover
# Run tests verbosely
go test ./... -v# Build for current platform
go build -o bcp
# Build with version info
go build -ldflags "-X main.Version=1.0.0" -o bcp- "bucket name is required": Set bucket via
--bucketflag or in config file - "invalid SSM instance ID": Ensure instance ID format is
i-xxxxxxxxx - "AWS CLI is not installed on instance": Install AWS CLI on the remote instance
- "operation failed after N retries": Check network connectivity and AWS credentials
bcp ./files i-xxx:/tmp/files --bucket my-bucket --verboseContributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request