--- AWSTemplateFormatVersion: 2010-09-09 Description: > This template deploys a Retail Demo Store Service. Parameters: ServiceName: Type: String ClusterName: Type: String DesiredCount: Type: Number Default: 1 ContainerCpu: Type: Number ContainerMemory: Type: Number TargetGroup: Type: String SourceSecurityGroup: Type: AWS::EC2::SecurityGroup::Id Subnets: Type: List ContainerPort: Type: String Default: 80 ContainerImage: Type: String Default: amazon/amazon-ecs-sample ServiceDiscoveryNamespace: Type: String EnvPersonalizeCampaignArn: Type: String Default: none EnvPersonalizeSearchCampaignArn: Type: String Default: none EnvProductsServiceInternalUrl: Type: String Default: products.retaildemostore.local EnvProductsServiceInternalPort: Type: String Default: 80 EnvUsersServiceInternalUrl: Type: String Default: users.retaildemostore.local EnvUsersServiceInternalPort: Type: String Default: 80 EnvSearchServiceInternalUrl: Type: String Default: search.retaildemostore.local EnvSerchServiceInternalPort: Type: String Default: 80 EnvOffersServiceInternalUrl: Type: String Default: offers.retaildemostore.local EnvOffersServiceInternalPort: Type: String Default: 80 EnvOpenSearchDomainEndpoint: Type: String Default: none ResourceBucket: Type: String Default: none ParameterIVSVideoChannelMap: Type: String Default: none UseDefaultIVSStreams: Type: String Default: false WebRootUrl: Type: String Description: Public facing root URL where the Retail Demo Store web user interface is served. Used when building fully qualified URLs for the web user interface. AllowedPattern: "^https?://[^\\s/$.?#].[^\\s]*$" ConstraintDescription: Must be a valid URL referring to the root domain where web assets are located ImageRootUrl: Type: String Description: URL where Retail Demo Store images such as product images are located AllowedPattern: "^https?://[^\\s/$.?#].[^\\s]*$" ConstraintDescription: Must be a valid URL referring to the root path where images are located ProductsTable: Type: String Default: none CategoriesTable: Type: String Default: none ExperimentStrategyTable: Type: String Default: none Uid: Type: String PinpointAppId: Type: String EvidentlyProjectName: Type: String Description: Evidently project name Resources: TaskExecutionRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ecs-tasks.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy Policies: - PolicyName: ReadRetailDemoStoreSSMParams PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ssm:GetParameters Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore*' TaskRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: 'sts:AssumeRole' Policies: - PolicyName: DynamoDB PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:* Resource: - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${ProductsTable}' - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${CategoriesTable}' - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${ExperimentStrategyTable}' - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${ProductsTable}/index/*' - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${CategoriesTable}/index/*' - !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${ExperimentStrategyTable}/index/*' - PolicyName: PinpointSMS PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - mobiletargeting:SendMessages - mobiletargeting:GetEndpoint - mobiletargeting:UpdateEndpoint - mobiletargeting:PutEvents Resource: !Sub 'arn:aws:mobiletargeting:${AWS::Region}:${AWS::AccountId}:apps/*' - Effect: Allow Action: - mobiletargeting:PhoneNumberValidate Resource: !Sub 'arn:aws:mobiletargeting:${AWS::Region}:${AWS::AccountId}:phone/number/validate' - PolicyName: others PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ssm:* Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore*' - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' - Effect: Allow Action: - personalize:CreateSchema - personalize:CreateDatasetGroup - personalize:CreateSolutionVersion - personalize:CreateDatasetImportJob - personalize:CreateSolution - personalize:DescribeDatasetGroup - personalize:DescribeDatasetImportJob - personalize:DescribeSolution - personalize:DescribeSolutionVersion - personalize:DescribeEventTracker - personalize:DescribeCampaign - personalize:DescribeRecommender - personalize:CreateCampaign - personalize:CreateDataset - personalize:CreateEventTracker - personalize:CreateFilter - personalize:GetPersonalizedRanking - personalize:GetRecommendations - personalize:DeleteEventTracker - personalize:DescribeEventTracker Resource: - !Sub 'arn:aws:personalize:${AWS::Region}:${AWS::AccountId}:*/retaildemo*' - Effect: Allow Action: - personalize:ListCampaigns - personalize:ListDatasetGroups - personalize:ListSolutions - personalize:ListSchemas - personalize:ListSolutionVersions - personalize:ListDatasetImportJobs - personalize:ListDatasets - personalize:ListEventTrackers Resource: - '*' - Effect: Allow Action: - s3:GetObject Resource: - !Sub 'arn:aws:s3:::${ResourceBucket}' - !Sub 'arn:aws:s3:::${ResourceBucket}/*' - Effect: Allow Action: - ivs:ListStreamKeys Resource: - !Sub 'arn:aws:ivs:${AWS::Region}:${AWS::AccountId}:*' - Effect: Allow Action: - ivs:GetChannel - ivs:GetStream - ivs:PutMetadata Resource: - !Sub 'arn:aws:ivs:${AWS::Region}:${AWS::AccountId}:channel/*' - Effect: Allow Action: - ivs:GetStreamKey Resource: - !Sub 'arn:aws:ivs:${AWS::Region}:${AWS::AccountId}:stream-key/*' - Effect: Allow Action: - events:DescribeRule - events:ListRules - events:EnableRule Resource: - !Sub 'arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/RetailDemoStore-PersonalizePreCreateScheduledRule' - Effect: Allow Action: - lambda:InvokeFunction Resource: - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:AmazonPaySigningLambda' - Effect: Allow Action: - evidently:BatchEvaluateFeature - evidently:PutProjectEvents Resource: - !Sub 'arn:aws:evidently:${AWS::Region}:${AWS::AccountId}:project/${EvidentlyProjectName}*' - !Sub 'arn:aws:evidently:${AWS::Region}:${AWS::AccountId}:project/${EvidentlyProjectName}/feature/*' ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSCloudMapDiscoverInstanceAccess - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /ecs/${AWS::StackName} FargateService: Type: AWS::ECS::Service Properties: Cluster: !Ref ClusterName DesiredCount: !Ref DesiredCount TaskDefinition: !Ref TaskDefinition LaunchType: FARGATE NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: DISABLED SecurityGroups: - !Ref SourceSecurityGroup Subnets: !Ref Subnets LoadBalancers: - ContainerName: !Ref ServiceName ContainerPort: !Ref ContainerPort TargetGroupArn: !Ref TargetGroup ServiceRegistries: - RegistryArn: !GetAtt ServiceDiscoveryService.Arn ContainerPort: !Ref ContainerPort ContainerName: !Ref ServiceName TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub ${AWS::StackName}-retaildemostore RequiresCompatibilities: - FARGATE Memory: !Ref ContainerMemory Cpu: !Ref ContainerCpu NetworkMode: awsvpc ExecutionRoleArn: !GetAtt 'TaskExecutionRole.Arn' #fix E3008 TaskRoleArn: !Ref TaskRole ContainerDefinitions: - Name: X-ray Image: public.ecr.aws/xray/aws-xray-daemon:alpha PortMappings: - ContainerPort: 2000 Protocol: udp - Name: !Ref ServiceName Image: !Ref ContainerImage Essential: true Memory: 256 Secrets: - Name: OPTIMIZELY_SDK_KEY ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore-optimizely-sdk-key' - Name: SEGMENT_WRITE_KEY ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore-segment-write-key' Environment: - Name: PERSONALIZE_CAMPAIGN_ARN Value: !Ref EnvPersonalizeCampaignArn - Name: SEARCH_CAMPAIGN_ARN Value: !Ref EnvPersonalizeSearchCampaignArn - Name: PRODUCTS_SERVICE_HOST Value: !Ref EnvProductsServiceInternalUrl - Name: PRODUCTS_SERVICE_PORT Value: '80' - Name: USERS_SERVICE_HOST Value: !Ref EnvUsersServiceInternalUrl - Name: USERS_SERVICE_PORT Value: '80' - Name: SEARCH_SERVICE_HOST Value: !Ref EnvSearchServiceInternalUrl - Name: SEARCH_SERVICE_PORT Value: '80' - Name: OFFERS_SERVICE_HOST Value: !Ref EnvOffersServiceInternalUrl - Name: OFFERS_SERVICE_PORT Value: '80' - Name: STACK_BUCKET Value: none - Name: RESOURCE_BUCKET Value: !Ref ResourceBucket - Name: PARAMETER_IVS_VIDEO_CHANNEL_MAP Value: !Ref ParameterIVSVideoChannelMap - Name: USE_DEFAULT_IVS_STREAMS Value: !Ref UseDefaultIVSStreams - Name: OPENSEARCH_DOMAIN_HOST Value: !Ref EnvOpenSearchDomainEndpoint - Name: OPENSEARCH_DOMAIN_PORT Value: '443' - Name: DDB_TABLE_PRODUCTS Value: !Ref ProductsTable - Name: DDB_TABLE_CATEGORIES Value: !Ref CategoriesTable - Name: WEB_ROOT_URL Value: !Ref WebRootUrl - Name: IMAGE_ROOT_URL Value: !Ref ImageRootUrl - Name: PERSONALIZE_PRECREATE_CAMPAIGNS_EVENTRULENAME Value: 'RetailDemoStore-PersonalizePreCreateScheduledRule' - Name: PINPOINT_APP_ID Value: !Ref PinpointAppId - Name: EVIDENTLY_PROJECT_NAME Value: !Ref EvidentlyProjectName PortMappings: - ContainerPort: 80 LogConfiguration: LogDriver: awslogs Options: awslogs-region: !Ref AWS::Region awslogs-group: !Ref LogGroup awslogs-stream-prefix: !Ref AWS::StackName ServiceDiscoveryService: Type: AWS::ServiceDiscovery::Service Properties: Name: !Ref ServiceName DnsConfig: DnsRecords: [{Type: SRV, TTL: 10}] NamespaceId: !Ref ServiceDiscoveryNamespace HealthCheckCustomConfig: FailureThreshold: 1 Outputs: FargateServiceArn: Value: !Ref FargateService FargateServiceName: Value: !GetAtt FargateService.Name TaskRoleArn: Value: !GetAtt TaskRole.Arn TaskExecutionRoleArn: Value: !GetAtt TaskExecutionRole.Arn