fleet/tools/redis-tests/elasticache/deploy-test-env.sh
Scott Gress 602f5a470b
Feat 1817 add iam auth to mysql and redis (#32488)
for #1817 

# Details

This PR gives Fleet servers the ability to connect to RDS MySQL and
Elasticache Redis via AWS [Identity and Access Management
(IAM)](https://aws.amazon.com/iam/). It is based almost entirely on the
work of @titanous, branched from his [original pull
request](https://github.com/fleetdm/fleet/pull/31075). The main
differences between his branch and this are:

1. Removal of auto-detection of AWS region (and cache name for
Elasticache) in favor of specifying these values in configuration. The
auto-detection is admittedly handy but parsing AWS host URLs is not
considered a best practice.
2. Relying on the existence of these new configs to determine whether or
not to connect via IAM. This sidesteps a thorny issue of whether to try
an IAM-based Elasticache connection when a password is not supplied,
since this is technically a valid setup.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually - besides using
@titanous's excellent test tool, I verified the following end-to-end:
  - [X] regular (non RDS) MySQL connection
  - [X] RDS MySQL connection using username/password
  - [X] RDS MySQL connection using IAM (no role)
  - [X] RDS MySQL connection using IAM (assuming role)
  - [X] regular (non Elasticache) Redis connection
  - [X] Elasticache Redis connection using username/password
  - [X] Elasticache Redis connection using NO password (without IAM)
  - [X] Elasticache Redis connection using IAM (no role)
  - [X] Elasticache Redis connection using IAM (assuming role)

---------

Co-authored-by: Jonathan Rudenberg <jonathan@titanous.com>
Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-04 10:08:47 -05:00

93 lines
No EOL
2.9 KiB
Bash
Executable file

#!/bin/bash
set -euo pipefail
# Configuration - use environment variables or defaults
VPC_CIDR="10.0.0.0/16"
SUBNET_CIDR="10.0.1.0/24"
STACK_NAME="${STACK_NAME:-fleet-elasticache-iam-test}"
KEY_NAME="${KEY_NAME:-fleet-test-key-$(date +%s)}"
INSTANCE_TYPE="${INSTANCE_TYPE:-t3.micro}"
echo "🚀 Deploying test environment for ElastiCache IAM authentication"
echo "📦 Creating EC2 key pair..."
aws ec2 create-key-pair \
--key-name "$KEY_NAME" \
--query 'KeyMaterial' \
--output text > "${KEY_NAME}.pem"
chmod 600 "${KEY_NAME}.pem"
echo "✅ Key pair created: ${KEY_NAME}.pem"
echo "🏗️ Deploying CloudFormation stack..."
aws cloudformation create-stack \
--stack-name "$STACK_NAME" \
--template-body file://cf-template.yaml \
--parameters ParameterKey=KeyName,ParameterValue="$KEY_NAME" ParameterKey=InstanceType,ParameterValue="$INSTANCE_TYPE" \
--capabilities CAPABILITY_NAMED_IAM
echo "⏳ Waiting for stack creation to complete (this may take 5-10 minutes)..."
aws cloudformation wait stack-create-complete \
--stack-name "$STACK_NAME"
echo "✅ Stack created successfully!"
# Get outputs
CACHE_ENDPOINT=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query 'Stacks[0].Outputs[?OutputKey==`ServerlessCacheEndpoint`].OutputValue' \
--output text)
EC2_IP=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query 'Stacks[0].Outputs[?OutputKey==`EC2InstancePublicIP`].OutputValue' \
--output text)
EC2_ID=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query 'Stacks[0].Outputs[?OutputKey==`EC2InstanceId`].OutputValue' \
--output text)
CACHE_USER=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query 'Stacks[0].Outputs[?OutputKey==`CacheUser`].OutputValue' \
--output text)
echo "📋 Stack Outputs:"
echo " ElastiCache Endpoint: $CACHE_ENDPOINT"
echo " EC2 Public IP: $EC2_IP"
echo " EC2 Instance ID: $EC2_ID"
echo " Cache User: $CACHE_USER"
echo " SSH Key: ${KEY_NAME}.pem"
# Wait for instance to be ready
echo "⏳ Waiting for EC2 instance to be ready..."
aws ec2 wait instance-status-ok \
--instance-ids "$EC2_ID"
# Save connection info
cat > test-env-info.txt << EOF
CACHE_ENDPOINT=$CACHE_ENDPOINT
EC2_IP=$EC2_IP
EC2_ID=$EC2_ID
CACHE_USER=$CACHE_USER
SSH_KEY=${KEY_NAME}.pem
EOF
echo "✅ Test environment deployed successfully!"
echo ""
echo "📝 Next steps:"
echo "1. Cross-compile the test binary:"
echo " GOOS=linux GOARCH=amd64 go build -o iamconnect"
echo ""
echo "2. Copy the binary to EC2:"
echo " scp -i ${KEY_NAME}.pem iamconnect ec2-user@$EC2_IP:~/"
echo ""
echo "3. SSH to the instance:"
echo " ssh -i ${KEY_NAME}.pem ec2-user@$EC2_IP"
echo ""
echo "4. Run the test:"
echo " ./iamconnect -addr $CACHE_ENDPOINT:6379 -user $CACHE_USER"
echo ""
echo "To clean up when done:"
echo " ./cleanup-test-env.sh"