0
votes

I have written the below template to pick an environment based upon the user input. But I am getting error as "An error occurred (ValidationError) when calling the CreateStack operation: Template format error: [/Resources/Type] resource definition is malformed" .Please guide me what need to be changed and whether syntax is in right format.

    AWSTemplateFormatVersion: 2010-09-09
      Parameters:
          EnvironmentValue:
             AllowedValues:
               - PROD
               - TEST
             Description: 'Please select an Environment'
             Type: String
      Mappings:
          Environment:
             PROD:
                VPC: vpc-xxxxxxxx
                Subnets: 'subnet-xxxxx,subnet-xxxxx,subnet-xxxx'
                Securitygroups: 'sg-xxxx,sg-xxxx'

             TEST:
                VPC: vpc-xxxxx
                Subnets: 'subnet-xxxx,subnet-xxxxx'
                Securitygroups: 'sg-xxxx,sg-xxxxx'
       #Conditions:
       #    CreatePRODStack: !Equals [!Ref EnvironmentValue, PROD]
       #    CreateTESTStack: !Equals [!Ref EnvironmentValue, TEST]
       Resources:
          Type: 'AWS::Es:Domain'
             Properties:
               DomainName: EPD34
               ElasticsearchVersion: 6.5
               ElasticsearchClusterConfig:
                   DedicatedMasterEnabled: 'true'
                   InstanceCount: '2'
                   ZoneAwarenessEnabled: 'true'
                   InstanceType: r4.xlarge.elasticsearch
                   DedicatedMasterType: r4.xlarge.elasticsearch
                   DedicatedMasterCount: '2'
               EBSOptions:
                   EBSEnabled: true
                   Iops: 0
                   VolumeSize: 100
                   VolumeType: gp2
               VPCOptions: !FindInMap [Environment, !Ref 'EnvironmentValue', VPC]
               SubnetIds: !FindInMap [Environment, !Ref 'EnvironmentValue', Subnets]
               Securitygroups: !FindInMap [Environment, !Ref 'EnvironmentValue', Securitygroups]
               SnapshotOptions:
                      AutomatedSnapshotStartHour: '0'
          Type: 'AWS::IAM::Policy'
              Properties: 
                  PolicyDocument: YAML
                  PolicyName: prodtest

When the user gives input as Prod, the stack for Prod should be created in Cloudformation

2

2 Answers

2
votes

I'm seeing a few issues here:

1 - You haven't named your resources. 2 - Your indentinging looks incorrect, which is important for yaml 3 - I believe your Type for the Elasticsearch domain is incorrect. You have

Type: 'AWS::Es:Domain'

but I think it should be

Type: AWS::Elasticsearch::Domain

Using your Domain as an example, I think it should be more along the lines of:

ElasticsearchDomain:
    Type: AWS::Elasticsearch::Domain
    Properties:
        DomainName: EPD34
        ElasticsearchVersion: 6.5
        ElasticsearchClusterConfig:
            DedicatedMasterEnabled: 'true'
            InstanceCount: '2'
            ZoneAwarenessEnabled: 'true'
            InstanceType: r4.xlarge.elasticsearch
            DedicatedMasterType: r4.xlarge.elasticsearch
            DedicatedMasterCount: '2'
        EBSOptions:
            EBSEnabled: true
            Iops: 0
            VolumeSize: 100
            VolumeType: gp2
        VPCOptions: !FindInMap [Environment, !Ref 'EnvironmentValue', VPC]
        SubnetIds: !FindInMap [Environment, !Ref 'EnvironmentValue', Subnets]
        Securitygroups: !FindInMap [Environment, !Ref 'EnvironmentValue', Securitygroups]
        SnapshotOptions:
            AutomatedSnapshotStartHour: '0'

There may be other issues I'm missing here, but there are definitely syntax errors in here

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticsearch-domain.html

0
votes

The type tag is expected to be 'AWS::Elasticsearch::Domain' and there are multiple formatting errors as per the yaml declarations. The Properties should be at the same level as Type. Then VPCOptions should have the two properties following it. With the given example the template should look like the following

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  EnvironmentValue:
     AllowedValues:
       - PROD
       - TEST
     Description: 'Please select an Environment'
     Type: String
Mappings:
  Environment:
     PROD:
        VPC: vpc-xxxxxxxx
        Subnets: 'subnet-xxxxx,subnet-xxxxx,subnet-xxxx'
        Securitygroups: 'sg-xxxx,sg-xxxx'

     TEST:
        VPC: vpc-xxxxx
        Subnets: 'subnet-xxxx,subnet-xxxxx'
        Securitygroups: 'sg-xxxx,sg-xxxxx'
#Conditions:
#    CreatePRODStack: !Equals [!Ref EnvironmentValue, PROD]
#    CreateTESTStack: !Equals [!Ref EnvironmentValue, TEST]
Resources:
  ElasticSearchCluster:
        Type: 'AWS::Es:Domain'
        Properties:
            DomainName: EPD34
            ElasticsearchVersion: 6.5
            ElasticsearchClusterConfig:
            DedicatedMasterEnabled: 'true'
            InstanceCount: '2'
            ZoneAwarenessEnabled: 'true'
            InstanceType: r4.xlarge.elasticsearch
            DedicatedMasterType: r4.xlarge.elasticsearch
            DedicatedMasterCount: '2'
            EBSOptions:
                EBSEnabled: true
            Iops: 0
            VolumeSize: 100
            VolumeType: gp2
            VPCOptions: 
                SubnetIds: !FindInMap [Environment, !Ref 'EnvironmentValue', Subnets]
                Securitygroups: !FindInMap [Environment, !Ref 'EnvironmentValue', Securitygroups]
            SnapshotOptions:
                AutomatedSnapshotStartHour: '0'

    IAMPolicyEntry:             
        Type: 'AWS::IAM::Policy'
        Properties: 
            PolicyDocument: YAML
            PolicyName: prodtest