AWSTemplateFormatVersion: 2010-09-09 Description: Workload Discovery on AWS Opensearch Domain Stack Parameters: AppName: Description: Please specify the Application Name. Used for tagging and resource names. Mandatory LOWER CASE. Type: String PerspectiveVpcCidr: Description: VPC CIDR Type: String AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' ZoneAwarenessEnabled: Description: Multiple AZ deployment Type: String AllowedValues: - 'Yes' - 'No' PrivateSubnet0: Description: Private Subnet 0 Type: AWS::EC2::Subnet::Id PrivateSubnet1: Description: Private Subnet 1 Type: AWS::EC2::Subnet::Id PerspectiveVPCId: Description: The id that was assigned to the VPC created in VPC stack Type: AWS::EC2::VPC::Id SearchLambdaIAMRoleARN: Description: Role that lambda function will assume. Type: String InstanceType: Description: The instance type for data nodes Type: String Conditions: ZoneAwarenessEnabled: !Equals [ !Ref ZoneAwarenessEnabled, 'Yes' ] Resources: OpenSearchSg: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: !Sub ${AppName}-OS Security Group SecurityGroupEgress: - Description: Explicit egress group locking down outbound access HTTP CidrIp: !Ref PerspectiveVpcCidr IpProtocol: tcp ToPort: 80 FromPort: 80 - Description: Explicit egress group locking down outbound access for HTTPS CidrIp: !Ref PerspectiveVpcCidr IpProtocol: tcp ToPort: 443 FromPort: 443 VpcId: Ref: PerspectiveVPCId OpenSearchDomain: Type: AWS::OpenSearchService::Domain Properties: EngineVersion: OpenSearch_1.3 ClusterConfig: InstanceCount: !If [ZoneAwarenessEnabled, 2, 1] InstanceType: !Ref InstanceType ZoneAwarenessEnabled: !If [ZoneAwarenessEnabled, true, false] ZoneAwarenessConfig: !If - ZoneAwarenessEnabled - AvailabilityZoneCount: 2 - !Ref AWS::NoValue DedicatedMasterEnabled: false DomainEndpointOptions: EnforceHTTPS: true EBSOptions: EBSEnabled: true VolumeType: gp2 VolumeSize: 10 SnapshotOptions: AutomatedSnapshotStartHour: 0 AccessPolicies: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: Ref: SearchLambdaIAMRoleARN Action: - es:ESHttpHead - es:ESHttpGet - es:ESHttpPost - es:ESHttpPut - es:ESHttpDelete Resource: !Sub arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/* AdvancedOptions: rest.action.multi.allow_explicit_index: 'true' indices.query.bool.max_clause_count: '4096' EncryptionAtRestOptions: Enabled: true NodeToNodeEncryptionOptions: Enabled: true Tags: - Key: Name Value: !Sub ${AppName}-OS-Cluster - Key: App Value: !Ref AppName - Key: Version Value: '1.3' VPCOptions: SubnetIds: - !Ref PrivateSubnet0 - !If - ZoneAwarenessEnabled - !Ref PrivateSubnet1 - !Ref AWS::NoValue SecurityGroupIds: - !Ref OpenSearchSg UpdatePolicy: EnableVersionUpgrade: true ElasticSearchCPUUtilizationTooHighAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: OS cluster CPU usage above 80% ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: CPUUtilization Namespace: AWS/ES Period: 60 Statistic: Average Threshold: 80 ElasticSearchClusterStatusRedAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: OS cluster status red greater than 1 minute ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: ClusterStatus.red Namespace: AWS/ES Period: 60 Statistic: Average Threshold: 1 ElasticSearchClusterStatusYellowAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: OS cluster status yellow greater than 1 minute ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: ClusterStatus.yellow Namespace: AWS/ES Period: 60 Statistic: Maximum Threshold: 1 ElasticSearchClusterJVMMemoryPressureAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: OS cluster jvm mem pressure too high for more than 1 minute ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: JVMMemoryPressure Namespace: AWS/ES Period: 60 Statistic: Average Threshold: 85 ElasticSearchClusterIndexWritesBlockedAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: ES cluster index writes blocked more than 1 minute ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: ClusterIndexWritesBlocked Namespace: AWS/ES Period: 60 Statistic: Maximum Threshold: 1 ElasticSearchClusterAutomatedSnapshotFailureAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: ES cluster snapshot failed ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: missing Dimensions: - Name: ClientId Value: !Ref "AWS::AccountId" - Name: DomainName Value: !Ref OpenSearchDomain EvaluationPeriods: 5 MetricName: ClusterIndexWritesBlocked Namespace: AWS/ES Period: 60 Statistic: Maximum Threshold: 1 Outputs: DomainEndpoint: Value: !GetAtt OpenSearchDomain.DomainEndpoint OpenSearchSg: Value: !Ref OpenSearchSg