-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
317 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
# stacks/apps/dovetail-insights.yml | ||
# 200A | ||
# | ||
# The names of the SQS queues created by this template are intended to | ||
# implicitly match some configuration that exists within the CMS application. | ||
# The only part of the queue names that is passed to the application is the | ||
# prefix; if the stems change in other the template or the app config, things | ||
# will not function as expected. | ||
AWSTemplateFormatVersion: "2010-09-09" | ||
Transform: AWS::Serverless-2016-10-31 | ||
|
||
Description: >- | ||
Creates a dedicated load balancer and the ECS service for the public Insights | ||
web server. | ||
Parameters: | ||
kWebContainerName: | ||
Type: String | ||
Default: insights-web | ||
kWebApplicationPort: | ||
Type: Number | ||
Default: 3000 | ||
####### | ||
NestedChangeSetScrubbingResourcesState: { Type: String } | ||
AlbFullName: { Type: String } | ||
AlbHttpsListenerArn: { Type: String } | ||
EcsClusterArn: { Type: String } | ||
EnvironmentType: { Type: String } | ||
EnvironmentTypeAbbreviation: { Type: String } | ||
EnvironmentTypeLowercase: { Type: String } | ||
RegionMode: { Type: String } | ||
RootStackName: { Type: String } | ||
RootStackId: { Type: String } | ||
VpcId: { Type: AWS::EC2::VPC::Id } | ||
NewRelicApiKeyPrxLite: { Type: String } | ||
EcrImageTag: { Type: AWS::SSM::Parameter::Value<String> } | ||
AlbListenerRulePriorityPrefix: { Type: String } | ||
IdHostname: { Type: String } | ||
|
||
Conditions: | ||
IsProduction: !Equals [!Ref EnvironmentType, Production] | ||
IsPrimaryRegion: !Equals [!Ref RegionMode, Primary] | ||
EnableNestedChangeSetScrubbingResources: !Equals [!Ref NestedChangeSetScrubbingResourcesState, Enabled] | ||
|
||
Resources: | ||
NestedChangeSetScrubber: { Type: AWS::SNS::Topic, Condition: EnableNestedChangeSetScrubbingResources } | ||
|
||
HostHeaderListenerRule: | ||
Type: AWS::ElasticLoadBalancingV2::ListenerRule | ||
Properties: | ||
Actions: | ||
- TargetGroupArn: !Ref WebTargetGroup | ||
Type: forward | ||
Conditions: | ||
- Field: host-header | ||
Values: | ||
- insights.dovetail.* | ||
ListenerArn: !Ref AlbHttpsListenerArn | ||
Priority: !Join ["", [!Ref AlbListenerRulePriorityPrefix, "01"]] | ||
|
||
ExecutionRole: | ||
Type: AWS::IAM::Role | ||
Properties: | ||
AssumeRolePolicyDocument: | ||
Statement: | ||
- Action: sts:AssumeRole | ||
Effect: Allow | ||
Principal: | ||
Service: ecs-tasks.amazonaws.com | ||
Version: "2012-10-17" | ||
ManagedPolicyArns: | ||
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy | ||
Policies: | ||
- PolicyDocument: | ||
Statement: | ||
- Action: ssm:GetParameters | ||
Effect: Allow | ||
Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/prx/${EnvironmentTypeAbbreviation}/Spire/Dovetail-Insights/* | ||
Sid: AllowAppParameterRead | ||
Version: "2012-10-17" | ||
PolicyName: ContainerSecrets | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
TaskRole: | ||
Type: AWS::IAM::Role | ||
Properties: | ||
AssumeRolePolicyDocument: | ||
Statement: | ||
- Action: sts:AssumeRole | ||
Effect: Allow | ||
Principal: | ||
Service: ecs-tasks.amazonaws.com | ||
Version: "2012-10-17" | ||
Policies: | ||
- PolicyDocument: | ||
Statement: | ||
- Action: events:PutEvents | ||
Effect: Allow | ||
Resource: !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:event-bus/default | ||
Sid: AllowDefaultEventBusPut | ||
Version: "2012-10-17" | ||
PolicyName: DefaultEventBus | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
|
||
WebTargetGroup: | ||
Type: AWS::ElasticLoadBalancingV2::TargetGroup | ||
Properties: | ||
HealthCheckIntervalSeconds: 15 | ||
HealthCheckPath: /api/v1 | ||
HealthCheckTimeoutSeconds: 5 | ||
HealthyThresholdCount: 3 | ||
Port: 80 | ||
Protocol: HTTP | ||
TargetGroupAttributes: | ||
- Key: deregistration_delay.timeout_seconds | ||
Value: "30" | ||
Tags: | ||
- { Key: Name, Value: !Sub "${RootStackName}_insights" } | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
UnhealthyThresholdCount: 3 | ||
VpcId: !Ref VpcId | ||
WebTargetGroupHttp5xxAlarm: | ||
Type: AWS::CloudWatch::Alarm | ||
Condition: IsProduction | ||
Properties: | ||
AlarmName: !Sub ERROR [Insights] Web server <${EnvironmentTypeAbbreviation}> RETURNING 5XX ERRORS (${RootStackName}) | ||
AlarmDescription: !Sub >- | ||
${EnvironmentType} Insights' Rails server is returning 5XX errors from | ||
the ECS service to the load balancer. | ||
ComparisonOperator: GreaterThanThreshold | ||
Dimensions: | ||
- Name: LoadBalancer | ||
Value: !Ref AlbFullName | ||
- Name: TargetGroup | ||
Value: !GetAtt WebTargetGroup.TargetGroupFullName | ||
EvaluationPeriods: 1 | ||
MetricName: HTTPCode_Target_5XX_Count | ||
Namespace: AWS/ApplicationELB | ||
Period: 60 | ||
Statistic: Sum | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:ops:cloudwatch-log-group-name, Value: !Ref WebTaskLogGroup } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
Threshold: 0 | ||
TreatMissingData: notBreaching | ||
|
||
WebEcsService: | ||
Type: AWS::ECS::Service | ||
# Condition: HasAuroraEndpoint # See README | ||
Properties: | ||
Cluster: !Ref EcsClusterArn | ||
DeploymentConfiguration: | ||
MaximumPercent: 200 | ||
MinimumHealthyPercent: 50 | ||
DesiredCount: !If [IsPrimaryRegion, !If [IsProduction, 0, 0], 0] | ||
EnableECSManagedTags: true | ||
LoadBalancers: | ||
- ContainerName: !Ref kWebContainerName | ||
ContainerPort: !Ref kWebApplicationPort | ||
TargetGroupArn: !Ref WebTargetGroup | ||
PlacementConstraints: | ||
- Type: memberOf | ||
Expression: attribute:ecs.cpu-architecture == ARM64 | ||
PropagateTags: TASK_DEFINITION | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
TaskDefinition: !Ref WebTaskDefinition | ||
WebTaskLogGroup: | ||
Type: AWS::Logs::LogGroup | ||
DeletionPolicy: Delete | ||
UpdateReplacePolicy: Delete | ||
Properties: | ||
RetentionInDays: 14 | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
WebTaskDefinition: | ||
Type: AWS::ECS::TaskDefinition | ||
Properties: | ||
ContainerDefinitions: | ||
- Command: | ||
- web | ||
Cpu: !If [IsProduction, 200, 128] | ||
Environment: | ||
- Name: ID_HOST | ||
Value: !Ref IdHostname | ||
- Name: NEW_RELIC_KEY | ||
Value: !Ref NewRelicApiKeyPrxLite | ||
- Name: NEW_RELIC_NAME | ||
Value: !If [IsProduction, Insights Production, Insights Staging] | ||
- Name: PORT | ||
Value: !Ref kWebApplicationPort | ||
- Name: RAILS_ENV | ||
Value: !Ref EnvironmentTypeLowercase | ||
Essential: true | ||
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrImageTag} | ||
LinuxParameters: | ||
InitProcessEnabled: true | ||
LogConfiguration: | ||
LogDriver: awslogs | ||
Options: | ||
awslogs-group: !Ref WebTaskLogGroup | ||
awslogs-region: !Ref AWS::Region | ||
awslogs-stream-prefix: ecs | ||
Memory: !If [IsProduction, 2000, 1000] | ||
MemoryReservation: !If [IsProduction, 1000, 500] | ||
Name: !Ref kWebContainerName | ||
PortMappings: | ||
- ContainerPort: !Ref kWebApplicationPort | ||
HostPort: 0 | ||
# Secrets: | ||
# - Name: API_ADMIN_TOKENS | ||
# ValueFrom: !Sub /prx/${EnvironmentTypeAbbreviation}/Spire/Dovetail-Feeder/api-admin-tokens | ||
ExecutionRoleArn: !GetAtt ExecutionRole.Arn | ||
NetworkMode: bridge | ||
Tags: | ||
- { Key: prx:meta:tagging-version, Value: "2021-04-07" } | ||
- { Key: prx:cloudformation:stack-name, Value: !Ref AWS::StackName } | ||
- { Key: prx:cloudformation:stack-id, Value: !Ref AWS::StackId } | ||
- { Key: prx:cloudformation:root-stack-name, Value: !Ref RootStackName } | ||
- { Key: prx:cloudformation:root-stack-id, Value: !Ref RootStackId } | ||
- { Key: prx:ops:environment, Value: !Ref EnvironmentType } | ||
- { Key: prx:dev:family, Value: Dovetail } | ||
- { Key: prx:dev:application, Value: Insights } | ||
TaskRoleArn: !GetAtt TaskRole.Arn | ||
|
||
Outputs: | ||
WebTargetGroupFullName: | ||
Value: !GetAtt WebTargetGroup.TargetGroupFullName |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters