--- AWSTemplateFormatVersion: "2010-09-09" Description: "Creates a VPC with Managed NAT, a RDS MySQL instance, an ALB, and an EFS filesystem)" Parameters: VPCName: Description: The name of the VPC being created. Type: String Default: "Wordpress on Fargate base infrastructure" Mappings: SubnetConfig: VPC: CIDR: "10.0.0.0/16" Public0: CIDR: "10.0.0.0/24" Public1: CIDR: "10.0.1.0/24" Private0: CIDR: "10.0.2.0/24" Private1: CIDR: "10.0.3.0/24" # This mapping accounts for the scenario when certain AZs # are not available to use (this differs on a per account # per customer basis). E.g., if the 'b' AZ is not available # in a specific region in one's account then updating the # list contained in the mapping below here will allow a # different AZ to be chosen. AZRegions: ap-northeast-1: AZs: ["a", "b"] ap-northeast-2: AZs: ["a", "b"] ap-south-1: AZs: ["a", "b"] ap-southeast-1: AZs: ["a", "b"] ap-southeast-2: AZs: ["a", "b"] ca-central-1: AZs: ["a", "b"] eu-central-1: AZs: ["a", "b"] eu-west-1: AZs: ["a", "b"] eu-west-2: AZs: ["a", "b"] sa-east-1: AZs: ["a", "b"] us-east-1: AZs: ["a", "b"] us-east-2: AZs: ["a", "b"] us-west-1: AZs: ["c", "b"] us-west-2: AZs: ["a", "b"] Resources: VPC: Type: "AWS::EC2::VPC" Properties: EnableDnsSupport: "true" EnableDnsHostnames: "true" CidrBlock: Fn::FindInMap: - "SubnetConfig" - "VPC" - "CIDR" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Ref 'VPCName' PublicSubnet0: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Public0" - "CIDR" MapPublicIpOnLaunch: "true" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-public-' - !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] PublicSubnet1: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Public1" - "CIDR" MapPublicIpOnLaunch: "true" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-public-' - !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] PrivateSubnet0: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Private0" - "CIDR" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Private" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-private-' - !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] PrivateSubnet1: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Private1" - "CIDR" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Private" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-private-' - !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] InternetGateway: Type: "AWS::EC2::InternetGateway" Properties: Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-IGW' GatewayToInternet: Type: "AWS::EC2::VPCGatewayAttachment" Properties: VpcId: Ref: "VPC" InternetGatewayId: Ref: "InternetGateway" PublicRouteTable: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-public-route-table' PublicRoute: Type: "AWS::EC2::Route" DependsOn: "GatewayToInternet" Properties: RouteTableId: Ref: "PublicRouteTable" DestinationCidrBlock: "0.0.0.0/0" GatewayId: Ref: "InternetGateway" PublicSubnetRouteTableAssociation0: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PublicSubnet0" RouteTableId: Ref: "PublicRouteTable" PublicSubnetRouteTableAssociation1: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PublicSubnet1" RouteTableId: Ref: "PublicRouteTable" PublicNetworkAcl: Type: "AWS::EC2::NetworkAcl" Properties: VpcId: Ref: "VPC" Tags: - Key: "Application" Value: Ref: "AWS::StackName" - Key: "Network" Value: "Public" - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-public-nacl' InboundHTTPPublicNetworkAclEntry: Type: "AWS::EC2::NetworkAclEntry" Properties: NetworkAclId: Ref: "PublicNetworkAcl" RuleNumber: "100" Protocol: "-1" RuleAction: "allow" Egress: "false" CidrBlock: "0.0.0.0/0" PortRange: From: "0" To: "65535" OutboundPublicNetworkAclEntry: Type: "AWS::EC2::NetworkAclEntry" Properties: NetworkAclId: Ref: "PublicNetworkAcl" RuleNumber: "100" Protocol: "-1" RuleAction: "allow" Egress: "true" CidrBlock: "0.0.0.0/0" PortRange: From: "0" To: "65535" PublicSubnetNetworkAclAssociation0: Type: "AWS::EC2::SubnetNetworkAclAssociation" Properties: SubnetId: Ref: "PublicSubnet0" NetworkAclId: Ref: "PublicNetworkAcl" PublicSubnetNetworkAclAssociation1: Type: "AWS::EC2::SubnetNetworkAclAssociation" Properties: SubnetId: Ref: "PublicSubnet1" NetworkAclId: Ref: "PublicNetworkAcl" ElasticIP0: Type: "AWS::EC2::EIP" Properties: Domain: "vpc" ElasticIP1: Type: "AWS::EC2::EIP" Properties: Domain: "vpc" NATGateway0: Type: "AWS::EC2::NatGateway" Properties: AllocationId: Fn::GetAtt: - "ElasticIP0" - "AllocationId" SubnetId: Ref: "PublicSubnet0" NATGateway1: Type: "AWS::EC2::NatGateway" Properties: AllocationId: Fn::GetAtt: - "ElasticIP1" - "AllocationId" SubnetId: Ref: "PublicSubnet1" PrivateRouteTable0: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" Tags: - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-private-route-table-0' PrivateRouteTable1: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" Tags: - Key: "Name" Value: !Join - '' - - !Ref "VPCName" - '-private-route-table-1' PrivateRouteToInternet0: Type: "AWS::EC2::Route" Properties: RouteTableId: Ref: "PrivateRouteTable0" DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: Ref: "NATGateway0" PrivateRouteToInternet1: Type: "AWS::EC2::Route" Properties: RouteTableId: Ref: "PrivateRouteTable1" DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: Ref: "NATGateway1" PrivateSubnetRouteTableAssociation0: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PrivateSubnet0" RouteTableId: Ref: "PrivateRouteTable0" PrivateSubnetRouteTableAssociation1: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PrivateSubnet1" RouteTableId: Ref: "PrivateRouteTable1" FileSystem: Type: AWS::EFS::FileSystem Properties: Encrypted: true FileSystemTags: - Key: Name Value: Wordpress-demo PerformanceMode: generalPurpose ThroughputMode: bursting MountTargetSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: FileSystem Security Group VpcId: !Ref VPC GroupName: Wordpress-Demo-EFS-SG SecurityGroupIngress: - IpProtocol: "tcp" FromPort: 2049 ToPort: 2049 CidrIp: 10.0.0.0/16 MountTarget1: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystem SubnetId: !Ref PrivateSubnet0 SecurityGroups: - !Ref MountTargetSecurityGroup MountTarget2: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystem SubnetId: !Ref PrivateSubnet1 SecurityGroups: - !Ref MountTargetSecurityGroup AccessPoint: Type: AWS::EFS::AccessPoint Properties: FileSystemId: !Ref FileSystem PosixUser: Uid: "1000" Gid: "1000" RootDirectory: CreationInfo: OwnerGid: "1000" OwnerUid: "1000" Permissions: "0777" Path: "/bitnami" DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupName: wp-db-subnet-group DBSubnetGroupDescription: wp-db-subnet-group SubnetIds: - !Ref PublicSubnet0 - !Ref PublicSubnet1 DBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: RDS Security Group VpcId: !Ref VPC GroupName: Wordpress-Demo-RDS-SG SecurityGroupIngress: - IpProtocol: "tcp" FromPort: 3306 ToPort: 3306 CidrIp: 10.0.0.0/16 WordpressDB: Type: AWS::RDS::DBInstance Properties: DBInstanceIdentifier: wp-db1 DBInstanceClass: db.t3.micro DBName: wordpress Engine: mysql MasterUserPassword: supersecretpassword MasterUsername: admin PubliclyAccessible: false AllocatedStorage: 20 DBSubnetGroupName: !Ref DBSubnetGroup VPCSecurityGroups: - !Ref DBSecurityGroup ALBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: ALB Security Group VpcId: !Ref VPC GroupName: Wordpress-Demo-ALB-SG SecurityGroupIngress: - IpProtocol: "tcp" FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 WordPressALB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: wof-load-balancer SecurityGroups: - !Ref ALBSecurityGroup Subnets: - !Ref PublicSubnet0 - !Ref PublicSubnet1 WordPressTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: WordPressTargetGroup TargetType: ip Port: 8080 Protocol: HTTP HealthCheckPort: 8080 VpcId: !Ref VPC WordPressALBListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref WordPressALB Protocol: "HTTP" Port: 80 DefaultActions: - Type: forward ForwardConfig: TargetGroups: - TargetGroupArn: !Ref WordPressTargetGroup Weight: 1 Outputs: VPCId: Description: "VPCId of VPC" Value: Ref: "VPC" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-VPC" PublicSubnet0: Description: "SubnetId of public subnet 0" Value: Ref: "PublicSubnet0" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-PublicSubnet0" PublicSubnet1: Description: "SubnetId of public subnet 1" Value: Ref: "PublicSubnet1" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-PublicSubnet1" PrivateSubnet0: Description: "SubnetId of private subnet 0" Value: Ref: "PrivateSubnet0" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-PrivateSubnet0" PrivateSubnet1: Description: "SubnetId of private subnet 1" Value: Ref: "PrivateSubnet1" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-PrivateSubnet1" DefaultSecurityGroup: Description: "DefaultSecurityGroup Id" Value: !GetAtt VPC.DefaultSecurityGroup Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-DefaultSecurityGroup" EFSFSId: Description: "ID of EFS FS" Value: Ref: "FileSystem" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-FileSystem" RDSEndpointAddress: Description: "RDS Endpoint Address" Value: !GetAtt WordpressDB.Endpoint.Address Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-WordpressDB" EFSAccessPoint: Description: "EFS Access Point ID" Value: !GetAtt AccessPoint.AccessPointId Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-AccessPoint" ALBSecurityGroup: Description: "ALB Security Group" Value: !GetAtt ALBSecurityGroup.GroupId Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-ALBSecurityGroup" WordPressTargetGroup: Description: "ALB Target Group" Value: Ref: "WordPressTargetGroup" Export: Name: !Sub "${AWS::Region}-${AWS::StackName}-ALBTargetGroup"