# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # Permission is hereby granted, free of charge, to any person obtaining a copy of this # software and associated documentation files (the "Software"), to deal in the Software # without restriction, including without limitation the rights to use, copy, modify, # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWSTemplateFormatVersion: 2010-09-09 Description: >- This template creates a Multi-AZ (two Availability Zones), multi-subnet VPC infrastructure and associates one Non RFC 1918 CIDR Block to the newly created VPC. **WARNING** This template creates AWS resources You will be billed for the AWS resources used if you create a stack from this template. Parameters: Environment: AllowedValues: - 'dev' - 'devops' - 'uat' Description: >- Set environment in which the VPC will be created. Type: String ApplicationName: Description: >- Application name. Type: String Default: demo-ALB AmiId: Type: String Description: >- Hardened AMI generated by Image Builder. InstanceType: Type: String Default: t3.large Description: Instance type to use to launch the Nginx instances. AllowedValues: - t3.nano - t3.micro - t3.small - t3.medium - t3.large - m4.large - m4.xlarge - m4.2xlarge - m5.large - m5.xlarge - m5.2xlarge - c4.large - c4.xlarge - c4.large - c5.large - c5.xlarge - c5.large ALBName: Type: String ALBScheme: Type: String Default: internet-facing ALBType: Type: String Default: application ALBIpAddressType: Type: String Default: ipv4 TargetGroupName: Type: String TGHealthCheckIntervalSeconds: Type: Number Default: 30 TGHealthCheckProtocol: Type: String Default: HTTP TGHealthyThresholdCount: Type: Number Default: 2 TGPort: Type: Number Default: 8080 TGProtocol: Type: String Default: HTTP TGType: Type: String Default: instance TGUnhealthyThresholdCount: Type: Number Default: 2 ListenerPort: Type: Number Default: 8080 ListenerProtocol: Type: String Default: HTTP ListenerDefaultActionsType: Type: String Default: forward NetworkStackName: Description: Stack name which has all of the VPC configuration Type: String S3IAMConfigStackName: Description: Stack name which has all of the Nginx S3 configuration Type: String InstanceProfileName: Type: String Description: Name of the Instance Profile Nginx Proxies will use Default: NginxInstanceProfile Resources: NginxInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Ref InstanceProfileName Roles: - Fn::ImportValue: !Sub "${S3IAMConfigStackName}-Nginx-Instance-Role-Name" Path: / ALBSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allows HTTP traffic to the Application Load Balancer SecurityGroupIngress: - CidrIp: Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" FromPort: 8080 ToPort: 8080 IpProtocol: tcp SecurityGroupEgress: - CidrIp: Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" FromPort: 8080 ToPort: 8080 IpProtocol: tcp Tags: - Key: Name Value: !Sub 'ALB SG - ${AWS::StackName}' VpcId: Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" NginxInstanceSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allows HTTP and HTTPS from vpc SecurityGroupIngress: - CidrIp: Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" FromPort: 8080 ToPort: 8080 IpProtocol: tcp - SourceSecurityGroupId: !Ref ALBSG FromPort: 8080 ToPort: 8080 IpProtocol: tcp Tags: - Key: Name Value: !Sub 'Nginx Instance SG - ${AWS::StackName}' VpcId: Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" LaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateData: InstanceType: !Ref InstanceType ImageId: !Ref AmiId IamInstanceProfile: Arn: Fn::GetAtt: - NginxInstanceProfile - Arn SecurityGroupIds: - !Ref NginxInstanceSG LaunchTemplateName: LaunchTemplate ALB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: !Ref ALBIpAddressType Name: !Ref ALBName Scheme: !Ref ALBScheme SecurityGroups: - !Ref ALBSG Subnets: - Fn::ImportValue: !Sub "${NetworkStackName}-PublicSubnet1AID" - Fn::ImportValue: !Sub "${NetworkStackName}-PublicSubnet2AID" Tags: - Key: Application Value: !Ref ApplicationName - Key: Environment Value: !Ref Environment Type: !Ref ALBType TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Ref TargetGroupName HealthCheckEnabled: true HealthCheckIntervalSeconds: !Ref TGHealthCheckIntervalSeconds HealthCheckProtocol: !Ref TGHealthCheckProtocol HealthyThresholdCount: !Ref TGHealthyThresholdCount HealthCheckPort: 8080 Port: !Ref TGPort Protocol: !Ref TGProtocol TargetType: !Ref TGType UnhealthyThresholdCount: !Ref TGUnhealthyThresholdCount VpcId: Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" NginxListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: !Ref ListenerDefaultActionsType TargetGroupArn: !Ref TargetGroup LoadBalancerArn: !Ref ALB Port: !Ref ListenerPort Protocol: !Ref ListenerProtocol NginxInstanceASG1: Type: AWS::AutoScaling::AutoScalingGroup Properties: DesiredCapacity: 2 HealthCheckGracePeriod: 300 HealthCheckType: EC2 LaunchTemplate: LaunchTemplateId: !Ref LaunchTemplate Version: !GetAtt LaunchTemplate.LatestVersionNumber MaxSize: 5 MinSize: 1 TargetGroupARNs: - Ref: TargetGroup VPCZoneIdentifier: - Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z1ID" - Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z2ID" Tags: - Key: Name Value: !Sub 'NginxInstance-${AWS::StackName}' PropagateAtLaunch: "true" TestingInstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM Policies: - PolicyName: root PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ec2:DescribeRegions Resource: '*' TestingInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref TestingInstanceRole Path: / TestingInstance: Type: AWS::EC2::Instance DependsOn: - NginxInstanceASG1 Properties: IamInstanceProfile: !Ref TestingInstanceProfile ImageId: !Ref AmiId InstanceType: t3.nano SecurityGroupIds: - !Ref LinuxPrivateSG SubnetId: Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z1ID" Tags: - Key: Name Value: !Sub 'TestingInstance-${AWS::StackName}' LinuxPrivateSG: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Linux EC2 Security Group SecurityGroupIngress: - IpProtocol: tcp CidrIp: Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" FromPort: 8080 ToPort: 8080 SecurityGroupEgress: - IpProtocol: tcp FromPort: 0 ToPort: 65535 CidrIp: 0.0.0.0/0 VpcId: Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" Outputs: ALB: Description: Nginx Network Load Balancer ARN Value: !Ref ALB Export: Name: !Sub '${AWS::StackName}-ALB' ALBDNSName: Description: Nginx Network Load Balancer DNS Name Value: !GetAtt ALB.DNSName Export: Name: !Sub "${AWS::StackName}-ALB-DNS-Name" InstanceProfileName: Description: Nginx Instance Profile Name Value: !Ref InstanceProfileName Export: Name: !Sub "${AWS::StackName}-Instance-Profile-Name" NginxInstanceSG: Description: Nginx Instance Security Group Value: !Ref NginxInstanceSG Export: Name: !Sub "${AWS::StackName}-Nginx-Instance-SG" NginxInstanceASG1: Description: Nginx Autoscaling Group Name Value: !Ref NginxInstanceASG1 Export: Name: !Sub "${AWS::StackName}-Nginx-Instance-ASG1"