AWSTemplateFormatVersion: 2010-09-09 Description: "This template creates the Base resources for the Microservice Observability with Amazon OpenSearch Service Workshop." Parameters: VpcCIDR: Type: String EnvironmentName: Type: String PublicSubnet1CIDR: Type: String PublicSubnet2CIDR: Type: String PublicSubnet3CIDR: Type: String PrivateSubnet1CIDR: Type: String PrivateSubnet2CIDR: Type: String PrivateSubnet3CIDR: Type: String NatGateway: Type: String Conditions: CreateNgwResource: !Equals [!Ref NatGateway, "Yes"] Resources: ######## Amazon VPC ######## VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Ref EnvironmentName - Key: IsUsedForDeploy Value: "True" InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Ref EnvironmentName InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC PublicSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref PublicSubnet1CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${EnvironmentName} Public Subnet (AZ1) PublicSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref PublicSubnet2CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${EnvironmentName} Public Subnet (AZ2) PublicSubnet3: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref PublicSubnet3CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${EnvironmentName} Public Subnet (AZ3) PrivateSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref PrivateSubnet1CIDR MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Subnet (AZ1) - Key: IsUsedForDeploy Value: "True" PrivateSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref PrivateSubnet2CIDR MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Subnet (AZ2) - Key: IsUsedForDeploy Value: "True" PrivateSubnet3: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref PrivateSubnet3CIDR MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Subnet (AZ3) - Key: IsUsedForDeploy Value: "True" NatGateway1EIP: Type: AWS::EC2::EIP Condition: CreateNgwResource DependsOn: InternetGatewayAttachment DeletionPolicy: Delete Properties: Domain: vpc NatGateway2EIP: Type: AWS::EC2::EIP Condition: CreateNgwResource DependsOn: InternetGatewayAttachment DeletionPolicy: Delete Properties: Domain: vpc NatGateway3EIP: Type: AWS::EC2::EIP Condition: CreateNgwResource DependsOn: InternetGatewayAttachment DeletionPolicy: Delete Properties: Domain: vpc NatGateway1: Type: AWS::EC2::NatGateway Condition: CreateNgwResource Properties: AllocationId: !GetAtt NatGateway1EIP.AllocationId SubnetId: !Ref PublicSubnet1 NatGateway2: Type: AWS::EC2::NatGateway Condition: CreateNgwResource Properties: AllocationId: !GetAtt NatGateway2EIP.AllocationId SubnetId: !Ref PublicSubnet2 NatGateway3: Type: AWS::EC2::NatGateway Condition: CreateNgwResource Properties: AllocationId: !GetAtt NatGateway3EIP.AllocationId SubnetId: !Ref PublicSubnet3 PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName} Public Routes DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet1 PublicSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet2 PublicSubnet3RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet3 PrivateRouteTable1: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Routes (AZ1) DefaultPrivateRoute1: Type: AWS::EC2::Route Condition: CreateNgwResource Properties: RouteTableId: !Ref PrivateRouteTable1 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway1 PrivateSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable1 SubnetId: !Ref PrivateSubnet1 PrivateRouteTable2: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Routes (AZ2) DefaultPrivateRoute2: Type: AWS::EC2::Route Condition: CreateNgwResource Properties: RouteTableId: !Ref PrivateRouteTable2 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway2 PrivateSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable2 SubnetId: !Ref PrivateSubnet2 PrivateRouteTable3: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName} Private Routes (AZ3) DefaultPrivateRoute3: Type: AWS::EC2::Route Condition: CreateNgwResource Properties: RouteTableId: !Ref PrivateRouteTable3 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway3 PrivateSubnet3RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable3 SubnetId: !Ref PrivateSubnet3 IngressSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "VPC Endpoint Ports Required" VpcId: !Ref VPC GroupName: "My SG Group VPC" SecurityGroupIngress: - FromPort: 443 IpProtocol: tcp ToPort: 443 CidrIp: !Ref VpcCIDR - FromPort: 80 IpProtocol: tcp ToPort: 80 CidrIp: !Ref VpcCIDR SecurityGroupEgress: - Description: Allow all outbound traffic IpProtocol: "-1" CidrIp: 0.0.0.0/0 CreateVpcEndpointSSM: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 - !Ref PrivateSubnet3 SecurityGroupIds: - !Ref IngressSecurityGroup PrivateDnsEnabled: true ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm VpcId: !Ref VPC CreateVpcEndpointSSMMessages: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 - !Ref PrivateSubnet3 SecurityGroupIds: - !Ref IngressSecurityGroup PrivateDnsEnabled: true ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages VpcId: !Ref VPC CreateVpcEndpointEC2Messages: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 - !Ref PrivateSubnet3 SecurityGroupIds: - !Ref IngressSecurityGroup PrivateDnsEnabled: true ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages VpcId: !Ref VPC ######## Amazon ECR Repositories ######## AnalyticsServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "analytics-service" DatabaseServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "database-service" OrderServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "order-service" InventoryServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "inventory-service" PaymentServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "payment-service" RecommendationServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "recommendation-service" AuthenticationServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "authentication-service" ClientServiceRepository: Type: AWS::ECR::Repository Properties: RepositoryName: "client-service" ######## Shared IAM Roles ######## AWSServiceRoleForAmazonOpenSearchService: Type: "AWS::IAM::ServiceLinkedRole" Properties: AWSServiceName: opensearchservice.amazonaws.com DeployCloudformationStackLambdaRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: AllowRolePassAndCF PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" - "iam:PassRole" - "iam:GetRole" - "iam:DetachRolePolicy" - "iam:DeleteRole" - "cloudformation:CreateStack" - "cloudformation:CreateChangeSet" - "cloudformation:DeleteStack" - "cloudformation:DescribeStacks" - "eks:DescribeCluster" - "eks:DescribeNodegroup" - "eks:DeleteCluster" - "eks:DeleteNodegroup" Resource: "*" EKSIAMRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - eks.amazonaws.com Action: - "sts:AssumeRole" ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy - arn:aws:iam::aws:policy/AmazonEKSServicePolicy Outputs: VPC: Value: !Ref VPC PublicSubnet1: Value: !Ref PublicSubnet1 PublicSubnet2: Value: !Ref PublicSubnet2 PublicSubnet3: Value: !Ref PublicSubnet3 PrivateSubnet1: Value: !Ref PrivateSubnet1 PrivateSubnet2: Value: !Ref PrivateSubnet2 PrivateSubnet3: Value: !Ref PrivateSubnet3 DeployCloudformationStackLambdaRole: Value: !GetAtt DeployCloudformationStackLambdaRole.Arn EKSIAMRole: Value: !GetAtt EKSIAMRole.Arn