Skip to content

Instantly share code, notes, and snippets.

@blohr-hs
Created January 29, 2018 22:54
Show Gist options
  • Save blohr-hs/a278438b0cf36346746f9602179a9abb to your computer and use it in GitHub Desktop.
Save blohr-hs/a278438b0cf36346746f9602179a9abb to your computer and use it in GitHub Desktop.
Description: >
Provides Grafana hosted on ECS Fargate.
Parameters:
LogCollectionStackName:
Description: Name of the CRM log collection stack which provides the Elasticsearch cluster for monitoring data
Type: String
Resources:
GrafanaCluster:
Type: AWS::ECS::Cluster
GrafanaService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref GrafanaCluster
DesiredCount: 1
LaunchType: FARGATE
TaskDefinition: !Ref TaskDefinition
LoadBalancers:
- ContainerName: grafana
ContainerPort: 3000
TargetGroupArn: !Ref TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
Subnets: !Split [",", !ImportValue "crm:private-subnets"]
SecurityGroups:
- !Ref GrafanaServiceSecurityGroup
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Cpu: 512
Memory: 1024
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ECSTaskExecutionRole" # TODO: Make this a standard role in some base layer stack
TaskRoleArn: !GetAtt TaskIamRole.Arn
ContainerDefinitions:
- Name: grafana
Image: grafana/grafana
Essential: true
PortMappings:
- ContainerPort: 3000
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref AWS::StackName
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: "grafana"
- Name: esProxy
Image: gorillastack/aws-es-proxy
Command:
- "./aws-es-proxy"
- "-verbose"
- "-listen"
- "0.0.0.0:9200"
- "-endpoint"
- Fn::ImportValue:
!Sub "${LogCollectionStackName}-ESEndpoint"
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref AWS::StackName
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: "esProxy"
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Ref AWS::StackName
RetentionInDays: 30
TaskIamRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: "ecs-tasks.amazonaws.com"
Action: "sts:AssumeRole"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Policies:
- PolicyName: GrafanaRolePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: "ReadCloudWatchMetrics"
Effect: Allow
Action:
- "cloudwatch:DescribeAlarmHistory"
- "cloudwatch:DescribeAlarms"
- "cloudwatch:DescribeAlarmsForMetric"
- "cloudwatch:GetMetricData"
- "cloudwatch:GetMetricStatistics"
- "cloudwatch:ListMetrics"
Resource: "*"
- Sid: "QueryESCluster"
Effect: Allow
Action:
- "es:ESHttpGet"
- "es:ESHttpHead"
Resource:
- Fn::ImportValue:
!Sub "${LogCollectionStackName}-ESDomainArn"
- Fn::Sub:
- "${esArn}/*"
- esArn:
Fn::ImportValue:
!Sub "${LogCollectionStackName}-ESDomainArn"
- Sid: "UseESMultisearch"
Effect: Allow
Action:
- "es:ESHttpPost"
Resource:
Fn::Sub:
- "${esArn}/_msearch"
- esArn:
Fn::ImportValue:
!Sub "${LogCollectionStackName}-ESDomainArn"
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Subnets: !Split [",", !ImportValue "crm:public-subnets"]
SecurityGroups:
- !Ref ALBSecurityGroup
# The various ALB components need explicit dependency ordering specified, or the target group
# will usually get done before the LB and cause the stack to fail.
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- LoadBalancer
- TargetGroup
Properties:
LoadBalancerArn: !Ref LoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn:
- LoadBalancer
Properties:
VpcId: !ImportValue "crm:vpc"
TargetType: ip
Port: 3000
Protocol: HTTP
HealthCheckIntervalSeconds: 5
HealthCheckPath: /login
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 3
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 5
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for the Grafana ALB"
SecurityGroupIngress:
- CidrIp: "0.0.0.0/0"
IpProtocol: "TCP"
FromPort: 80
ToPort: 80
- CidrIp: "0.0.0.0/0"
IpProtocol: "TCP"
FromPort: 443
ToPort: 443
VpcId: !ImportValue "crm:vpc"
GrafanaServiceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for the containers in Grafana service"
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref ALBSecurityGroup
IpProtocol: -1
VpcId: !ImportValue "crm:vpc"
Outputs:
GrafanaUrl:
Description: URL to the ALB that serves the Grafana front end
Value: !Sub "http://${LoadBalancer.DNSName}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment