Installation
Add the bundle to your composer.json:
composer require draw/aws-tool-kit-bundle
Enable it in config/bundles.php:
return [
// ...
Draw\AwsToolKitBundle\DrawAwsToolKitBundle::class => ['all' => true],
];
AWS Credentials Setup
Configure AWS credentials in .env:
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=your_region
First Use Case: Downloading CloudWatch Logs Run the command to fetch logs from CloudWatch:
bin/console draw:aws:cloud-watch-logs:download /aws/rds/cluster/prod-dbcluster/slowquery prod-1 ./tmp/slow-log.log
Verify the log file is created in ./tmp/slow-log.log.
Log Aggregation Workflow Use the command to periodically download logs from multiple RDS instances:
bin/console draw:aws:cloud-watch-logs:download /aws/rds/cluster/{cluster-name}/slowquery {instance-id} ./logs/{instance-id}.log --fileMode=a+
Schedule this via Symfony’s CronBundle or a CI/CD pipeline (e.g., daily at 2 AM).
Log Processing
Pipe logs to a local parser (e.g., jq, grep) or process them in PHP:
$logContent = file_get_contents('./tmp/slow-log.log');
$parsedLogs = explode("\n", $logContent);
Dynamic Log Paths
Store log paths in config/services.yaml and inject them:
parameters:
aws_log_paths:
rds_slow_queries: '/aws/rds/cluster/prod-dbcluster/slowquery'
Cron Job Safeguard Protect cron jobs from running on multiple instances by adding the flag:
bin/console acme:purge-database --aws-newest-instance-role=prod
Ensure the role (prod) matches the AWS IAM role assigned to your instances.
Integration with Symfony Commands Extend a custom command to enforce the role check:
use Draw\AwsToolKitBundle\Command\AwsNewestInstanceRoleTrait;
class MyCommand extends Command {
use AwsNewestInstanceRoleTrait;
protected function execute(InputInterface $input, OutputInterface $output): int {
$this->assertNewestInstanceRole($input->getOption('role'));
// Rest of the command logic
}
}
Role-Based Workflows Use the trait in background jobs (e.g., Symfony Messenger) to ensure idempotency:
$bus->dispatch(new MyJob(['role' => 'prod']));
Permissions Pitfalls
Ensure the IAM role has logs:GetLogEvents permissions. Test with:
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess --action-names logs:GetLogEvents
Log Retention
CloudWatch logs may expire. Use --start-time to fetch older logs:
bin/console draw:aws:cloud-watch-logs:download ... --start-time="2023-01-01T00:00:00Z"
File Mode Quirks
--fileMode=a+ appends logs but may truncate if the file is locked. Use w+ for fresh writes.
Role Naming The role must match the IAM role’s name exactly (case-sensitive). Verify with:
aws ec2 describe-tags --filters "Name=resource-id,Values=i-1234567890" "Name=key,Values=aws:ec2launchtemplate:role"
Debugging Failures If the command fails silently, enable debug mode:
bin/console debug:aws-newest-instance-role --role=prod --verbose
Check AWS metadata service access:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
Extension Points Override the role-checking logic by extending the trait:
protected function getInstanceMetadata(): array {
// Custom logic to fetch metadata (e.g., from a config file)
return ['InstanceId' => 'i-custom-id', 'Role' => 'custom-role'];
}
Testing Locally Mock the AWS SDK for local testing:
$this->mockAwsSdk('EC2', [
'describeInstances' => ['Instances' => [['Tags' => [['Key' => 'aws:ec2launchtemplate:role', 'Value' => 'prod']]]]]
]);
How can I help you explore Laravel packages today?