cloudformation/tag-manager.yaml (464 lines of code) (raw):

AWSTemplateFormatVersion: '2010-09-09' Description: tag-manager Parameters: Stage: Description: Environment name Type: String AllowedValues: - PROD - CODE Default: PROD VpcId: Description: ID of the VPC onto which to launch the application eg. vpc-1234abcd Type: AWS::EC2::VPC::Id Default: vpc-381fa95d PublicVpcSubnets: Description: Subnets to use in VPC for public internet-facing ELB eg. subnet-abcd1234 Type: List<AWS::EC2::Subnet::Id> Default: subnet-c3620fa6,subnet-2b37bd5c,subnet-3667c86f PrivateVpcSubnets: Description: Subnets to use in VPC for private EC2 instances eg. subnet-abcd1234 Type: List<AWS::EC2::Subnet::Id> Default: subnet-c2620fa7,subnet-2a37bd5d,subnet-2967c870 AMI: Description: AMI id Type: String GuardianIP: Description: Ip range for the office Type: String Default: 77.91.248.0/21 CertificateArn: Description: ARN of the SSL certificate for this service Type: String VulnerabilityScanningSecurityGroup: Description: Security group that grants access to the account's Vulnerability Scanner Type: AWS::EC2::SecurityGroup::Id CapiPreviewRole: Type: String Description: ARN of the CAPI preview role AlertTopicArn: Description: The ARN of the SNS topic to notify when an alarm occurs Type: AWS::SSM::Parameter::Value<String> Default: /account/services/alert.topic.arn LoggingStreamName: Type: AWS::SSM::Parameter::Value<String> Description: Name of the kinesis stream for logging to ELK (logs.gutools) Default: /account/services/logging.stream.name LoggingStreamArn: Type: AWS::SSM::Parameter::Value<String> Description: ARN of the kinesis stream for logging to ELK (logs.gutools) Default: /account/services/logging.stream Conditions: IsProd: !Equals [!Ref Stage, PROD] Mappings: Config: CODE: MinSize: 1 MaxSize: 2 DesiredCapacity: 1 InstanceType: t4g.medium DNSName: tagmanager.code.dev-gutools.co.uk PROD: MinSize: 3 MaxSize: 6 DesiredCapacity: 3 InstanceType: t4g.medium DNSName: tagmanager.gutools.co.uk Resources: TagManagerRole: Type: AWS::IAM::Role Properties: ManagedPolicyArns: - Fn::ImportValue: !Sub "guardian-ec2-for-ssm-GuardianEC2ForSSMPolicy" AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / TagManagerDescribeEC2Policy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagersDescribeEC2Policy PolicyDocument: Statement: - Effect: Allow Resource: "*" Action: - ec2:Describe* - autoscaling:DescribeAutoScalingGroups - autoscaling:DescribeAutoScalingInstances Roles: - !Ref 'TagManagerRole' TagManagerGetDistributablesPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerGetDistributablesPolicy PolicyDocument: Statement: - Effect: Allow Action: - s3:GetObject Resource: - arn:aws:s3:::composer-dist/* Roles: - !Ref 'TagManagerRole' TagManagerGetConfigPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerGetConfigPolicy PolicyDocument: Statement: - Effect: Allow Action: - s3:GetObject Resource: - arn:aws:s3:::guconf-flexible/tag-manager/* Roles: - !Ref 'TagManagerRole' TagManagerPanDomainPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerPanDomainPolicy PolicyDocument: Statement: - Effect: Allow Action: - s3:GetObject Resource: - arn:aws:s3:::pan-domain-auth-settings/* Roles: - !Ref 'TagManagerRole' TagManagerStaticFilesWritePolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerStaticFilesWritePolicy PolicyDocument: Statement: - Effect: Allow Action: sts:AssumeRole Resource: arn:aws:iam::642631414762:role/composerWriteToStaticBucket Roles: - !Ref 'TagManagerRole' TagManagerPermissionsBucketPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerPermissionsBucketPolicy PolicyDocument: Statement: - Effect: Allow Action: - s3:GetObject Resource: - arn:aws:s3:::permissions-cache/* Roles: - !Ref 'TagManagerRole' TagManagerCloudwatchPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerCloudwatchPolicy PolicyDocument: Statement: - Effect: Allow Action: - cloudwatch:* Resource: '*' Roles: - !Ref 'TagManagerRole' TagManagersDynamoPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerDynamoPolicy PolicyDocument: Statement: - Effect: Allow Action: - dynamodb:* Resource: '*' Roles: - !Ref 'TagManagerRole' TagManagerKinesisPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerKinesisPolicy PolicyDocument: Statement: - Effect: Allow Action: - kinesis:* Resource: '*' Roles: - !Ref 'TagManagerRole' TagManagerSQSPolicy: Type: AWS::IAM::Policy Properties: PolicyName: TagManagerSQSPolicy PolicyDocument: Statement: - Effect: Allow Action: - sqs:* Resource: '*' Roles: - !Ref 'TagManagerRole' LogServerPolicy: Type: AWS::IAM::Policy Properties: PolicyName: LogServerPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - kinesis:PutRecord - kinesis:PutRecords - kinesis:DescribeStream Resource: !Ref LoggingStreamArn Roles: - !Ref 'TagManagerRole' TagManagerInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref 'TagManagerRole' AppServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: tag manager Application servers VpcId: !Ref 'VpcId' SecurityGroupIngress: - IpProtocol: tcp FromPort: 9000 ToPort: 9000 CidrIp: !Ref 'GuardianIP' - IpProtocol: tcp FromPort: 9000 ToPort: 9000 SourceSecurityGroupId: !Ref 'LoadBalancerSecurityGroup' LoadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: tag manager application load balancer VpcId: !Ref 'VpcId' SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: '443' ToPort: '443' CidrIp: 0.0.0.0/0 TagManagerLoadBalancer: Type: AWS::ElasticLoadBalancing::LoadBalancer Properties: SecurityGroups: - !GetAtt [LoadBalancerSecurityGroup, GroupId] CrossZone: true Subnets: !Ref 'PublicVpcSubnets' Listeners: - LoadBalancerPort: '80' InstancePort: '9000' Protocol: HTTP - LoadBalancerPort: '443' InstancePort: '9000' Protocol: HTTPS SSLCertificateId: !Ref 'CertificateArn' HealthCheck: Target: HTTP:9000/management/healthcheck HealthyThreshold: '2' UnhealthyThreshold: '2' Interval: '10' Timeout: '5' Tags: - Key: Stage Value: !Ref 'Stage' - Key: Stack Value: flexible - Key: App Value: tag-manager TagManagerCloudfrontCachePolicy: Type: "AWS::CloudFront::CachePolicy" Properties: CachePolicyConfig: DefaultTTL: 0 MaxTTL: 3600 MinTTL: 0 Name: !Sub "tag-manager-cache-policy-${Stage}" ParametersInCacheKeyAndForwardedToOrigin: CookiesConfig: CookieBehavior: "all" EnableAcceptEncodingBrotli: true EnableAcceptEncodingGzip: true HeadersConfig: HeaderBehavior: "whitelist" Headers: - "Host" - "Origin" - "Access-Control-Request-Headers" - "Access-Control-Request-Method" - "X-Gu-Tools-HMAC-Token" - "X-Gu-Tools-HMAC-Date" - "X-Gu-Tools-Service-Name" QueryStringsConfig: QueryStringBehavior: "all" TagManagerCloudFrontDistribution: Type: "AWS::CloudFront::Distribution" Properties: DistributionConfig: Aliases: - !FindInMap [Config, !Ref 'Stage', DNSName] DefaultCacheBehavior: AllowedMethods: - "GET" - "HEAD" - "OPTIONS" - "PUT" - "PATCH" - "POST" - "DELETE" CachePolicyId: !Ref 'TagManagerCloudfrontCachePolicy' Compress: true TargetOriginId: !Ref 'TagManagerLoadBalancer' ViewerProtocolPolicy: "redirect-to-https" Enabled: true HttpVersion: "http2" IPV6Enabled: true Origins: - CustomOriginConfig: OriginProtocolPolicy: "https-only" OriginSSLProtocols: - "TLSv1.2" DomainName: !GetAtt TagManagerLoadBalancer.DNSName Id: !Ref 'TagManagerLoadBalancer' ViewerCertificate: AcmCertificateArn: !Sub '{{resolve:ssm:/${Stage}/flexible/tagmanager/cloudFrontCertificateArn}}' MinimumProtocolVersion: "TLSv1.2_2021" SslSupportMethod: "sni-only" Tags: - Key: "gu:repo" Value: "guardian/tagmanager" - Key: Stack Value: flexible - Key: Stage Value: !Ref 'Stage' - Key: App Value: tag-manager AutoscalingGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: AvailabilityZones: !GetAZs '' VPCZoneIdentifier: !Ref 'PrivateVpcSubnets' LaunchConfigurationName: !Ref 'TagManagerLaunchConfig' MinSize: !FindInMap [Config, !Ref 'Stage', MinSize] MaxSize: !FindInMap [Config, !Ref 'Stage', MaxSize] DesiredCapacity: !FindInMap [Config, !Ref 'Stage', DesiredCapacity] HealthCheckType: ELB HealthCheckGracePeriod: 300 LoadBalancerNames: - !Ref 'TagManagerLoadBalancer' Tags: - Key: Stage Value: !Ref 'Stage' PropagateAtLaunch: 'true' - Key: Stack Value: flexible PropagateAtLaunch: 'true' - Key: App Value: tag-manager PropagateAtLaunch: 'true' - Key: LogKinesisStreamName Value: !Ref 'LoggingStreamName' PropagateAtLaunch: 'true' - Key: SystemdUnit Value: tag-manager.service PropagateAtLaunch: 'true' TagManagerDNSRecord: Type: Guardian::DNS::RecordSet Properties: Name: !FindInMap [Config, !Ref 'Stage', DNSName] RecordType: CNAME ResourceRecords: - Fn::Join: - "" - - !GetAtt TagManagerCloudFrontDistribution.DomainName - "." Stage: !Ref Stage TTL: 3600 TagManagerLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: ImageId: !Ref 'AMI' SecurityGroups: - !Ref 'AppServerSecurityGroup' - !Ref 'VulnerabilityScanningSecurityGroup' InstanceType: !FindInMap [Config, !Ref 'Stage', InstanceType] IamInstanceProfile: !Ref 'TagManagerInstanceProfile' MetadataOptions: HttpTokens: required UserData: 'Fn::Base64': !Sub | #!/bin/bash -ev aws s3 cp s3://composer-dist/flexible/${Stage}/tag-manager/tag-manager.deb /tmp dpkg -i /tmp/tag-manager.deb AssumeCapiPreviewRolePolicy: Type: AWS::IAM::Policy Properties: PolicyName: assume-capi-preview-role PolicyDocument: Statement: - Effect: Allow Action: sts:AssumeRole Resource: Ref: CapiPreviewRole Roles: - Ref: TagManagerRole Tagmanager5XXAlarm: Type: AWS::CloudWatch::Alarm Condition: IsProd Properties: TreatMissingData: notBreaching AlarmDescription: Tag manager is returning 5x responses ComparisonOperator: GreaterThanOrEqualToThreshold Threshold: '10' EvaluationPeriods: '3' Metrics: - Expression: backend5XX + elb5XX Id: sum Label: "Count of Backend AND ELB 5XX" ReturnData: true - Id: backend5XX ReturnData: false Label: "backend5XX" MetricStat: Metric: MetricName: HTTPCode_Backend_5XX Namespace: AWS/ELB Dimensions: - Name: LoadBalancerName Value: !Ref 'TagManagerLoadBalancer' Period: 300 Stat: Sum Unit: Count - Id: elb5XX ReturnData: false Label: "elb5XX" MetricStat: Metric: MetricName: HTTPCode_ELB_5XX Namespace: AWS/ELB Dimensions: - Name: LoadBalancerName Value: !Ref 'TagManagerLoadBalancer' Period: 300 Stat: Sum Unit: Count AlarmActions: - !Ref 'AlertTopicArn' OKActions: - !Ref 'AlertTopicArn'