Deploy Alloy
This page guides you through deploying Grafana Alloy using a CloudFormation template. The template creates all required AWS resources with a single command.
This tutorial uses AWS CloudFormation because it requires no additional installation. For production deployments, consider translating the template to Terraform if your organization standardizes on it.
What the template creates
The CloudFormation template creates:
- An ECS Fargate cluster to run the Alloy container
- IAM roles for ECS task execution
- A CloudWatch log group for troubleshooting
- An ECS service that keeps Alloy running
You do not need to understand CloudFormation to use this template.
Create the template file
-
Run the following command to create the CloudFormation template file:
Terminal window cat > alloy-monitoring.yaml << 'EOF'AWSTemplateFormatVersion: '2010-09-09'Description: Deploy Grafana Alloy on ECS Fargate to monitor Aerospike CloudParameters:DatabaseHostname:Type: StringDescription: Your Aerospike Cloud database hostnameGrafanaRemoteWriteUrl:Type: StringDescription: Your Grafana Cloud Prometheus remote write URLGrafanaInstanceId:Type: StringDescription: Your Grafana Cloud instance ID (numeric)GrafanaApiToken:Type: StringNoEcho: trueDescription: Your Grafana Cloud API tokenSubnetId:Type: AWS::EC2::Subnet::IdDescription: Subnet ID in your VPC with peering to Aerospike CloudSecurityGroupId:Type: AWS::EC2::SecurityGroup::IdDescription: Security group allowing outbound to ports 9145 and 443Resources:ECSCluster:Type: AWS::ECS::ClusterProperties:ClusterName: alloy-monitoringLogGroup:Type: AWS::Logs::LogGroupProperties:LogGroupName: /ecs/alloy-aerospikeRetentionInDays: 7TaskExecutionRole:Type: AWS::IAM::RoleProperties:RoleName: alloy-task-execution-roleAssumeRolePolicyDocument:Version: '2012-10-17'Statement:- Effect: AllowPrincipal:Service: ecs-tasks.amazonaws.comAction: sts:AssumeRoleManagedPolicyArns:- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicyTaskRole:Type: AWS::IAM::RoleProperties:RoleName: alloy-task-roleAssumeRolePolicyDocument:Version: '2012-10-17'Statement:- Effect: AllowPrincipal:Service: ecs-tasks.amazonaws.comAction: sts:AssumeRoleTaskDefinition:Type: AWS::ECS::TaskDefinitionProperties:Family: alloy-aerospikeNetworkMode: awsvpcRequiresCompatibilities:- FARGATECpu: '256'Memory: '512'ExecutionRoleArn: !GetAtt TaskExecutionRole.ArnTaskRoleArn: !GetAtt TaskRole.ArnContainerDefinitions:- Name: alloyImage: grafana/alloy:latestEssential: trueEnvironment:- Name: ALLOY_DATABASE_HOSTNAMEValue: !Ref DatabaseHostname- Name: ALLOY_GRAFANA_URLValue: !Ref GrafanaRemoteWriteUrl- Name: ALLOY_GRAFANA_USERValue: !Ref GrafanaInstanceId- Name: ALLOY_GRAFANA_TOKENValue: !Ref GrafanaApiTokenEntryPoint:- /bin/sh- -cCommand:- printf 'prometheus.scrape "aerospike" {\n targets = [{"__address__" = "%s:9145"}]\n scrape_interval = "15s"\n forward_to = [prometheus.remote_write.grafana_cloud.receiver]\n}\nprometheus.remote_write "grafana_cloud" {\n endpoint {\n url = "%s"\n basic_auth {\n username = "%s"\n password = "%s"\n }\n }\n}\n' "$ALLOY_DATABASE_HOSTNAME" "$ALLOY_GRAFANA_URL" "$ALLOY_GRAFANA_USER" "$ALLOY_GRAFANA_TOKEN" > /tmp/config.alloy && /bin/alloy run /tmp/config.alloyLogConfiguration:LogDriver: awslogsOptions:awslogs-group: /ecs/alloy-aerospikeawslogs-region: !Ref AWS::Regionawslogs-stream-prefix: alloyECSService:Type: AWS::ECS::ServiceProperties:ServiceName: alloy-aerospikeCluster: !Ref ECSClusterTaskDefinition: !Ref TaskDefinitionDesiredCount: 1LaunchType: FARGATENetworkConfiguration:AwsvpcConfiguration:Subnets:- !Ref SubnetIdSecurityGroups:- !Ref SecurityGroupIdAssignPublicIp: ENABLEDOutputs:ClusterName:Description: ECS Cluster nameValue: !Ref ECSClusterServiceName:Description: ECS Service nameValue: !Ref ECSServiceLogGroupName:Description: CloudWatch Log Group for troubleshootingValue: !Ref LogGroupEOF -
Verify the file was created:
Terminal window ls -la alloy-monitoring.yaml
Deploy the stack
-
Run the CloudFormation deploy command. Replace the placeholder values with your information from the prerequisites:
Terminal window aws cloudformation deploy \--template-file alloy-monitoring.yaml \--stack-name alloy-monitoring \--capabilities CAPABILITY_NAMED_IAM \--parameter-overrides \DatabaseHostname=DATABASE_HOSTNAME \GrafanaRemoteWriteUrl=GRAFANA_REMOTE_WRITE_URL \GrafanaInstanceId=GRAFANA_INSTANCE_ID \GrafanaApiToken=GRAFANA_API_TOKEN \SubnetId=SUBNET_ID \SecurityGroupId=SECURITY_GROUP_IDReplace:
DATABASE_HOSTNAME- Your Aerospike Cloud database hostnameGRAFANA_REMOTE_WRITE_URL- Your Grafana Cloud Prometheus remote write URLGRAFANA_INSTANCE_ID- Your Grafana Cloud instance ID (numeric)GRAFANA_API_TOKEN- Your Grafana Cloud API tokenSUBNET_ID- Your VPC subnet IDSECURITY_GROUP_ID- Your security group ID
Waiting for changeset to be created..Waiting for stack create/update to completeSuccessfully created/updated stack - alloy-monitoringExpected result (after 2-3 minutes)
The deployment takes 2-3 minutes. CloudFormation creates the resources in the correct order and waits for each to be ready.
Verify the deployment
-
Check that the ECS service is running:
Terminal window aws ecs describe-services \--cluster alloy-monitoring \--services alloy-aerospike \--query 'services[0].{Status:status,Running:runningCount,Desired:desiredCount}'{"Status": "ACTIVE","Running": 1,"Desired": 1}Expected result If
Runningis 0, wait 30 seconds and try again. -
Check the container logs for any errors:
Terminal window aws logs tail /ecs/alloy-aerospike --since 5mYou should see Alloy startup messages. Look for lines indicating successful scraping.