I use a template cloud formation to create my cluster on aws :
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploys an EKS cluster in a new VPC (qs-1p7nknoht)
Metadata:
LintSpellExclude:
- Kubernetes
- ARNs
- Resource Names
- autoscaler
- IOPS
- EfsStorageClass
- Lambda
- maxIO
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: VPC network configuration
Parameters:
- NumberOfAZs
- AvailabilityZones
- VPCCIDR
- PrivateSubnet1CIDR
- PrivateSubnet2CIDR
- PrivateSubnet3CIDR
- PublicSubnet1CIDR
- PublicSubnet2CIDR
- PublicSubnet3CIDR
- RemoteAccessCIDR
- ProvisionBastionHost
- Label:
default: Amazon EC2 configuration
Parameters:
- KeyPairName
- Label:
default: Amazon EKS configuration
Parameters:
- NodeInstanceType
- NumberOfNodes
- MaxNumberOfNodes
- NodeGroupName
- NodeVolumeSize
- ManagedNodeGroup
- ManagedNodeGroupAMIType
- AdditionalEKSAdminArns
- KubernetesVersion
- Label:
default: Optional Kubernetes add-ins
Parameters:
- ClusterAutoScaler
- EfsStorageClass
- EfsPerformanceMode
- EfsThroughputMode
- EfsProvisionedThroughputInMibps
- MonitoringStack
- Label:
default: AWS Quick Start configuration
Parameters:
- QSS3BucketName
- QSS3KeyPrefix
- QSS3BucketRegion
- LambdaZipsBucketName
ParameterLabels:
AvailabilityZones:
default: Availability Zones
KeyPairName:
default: SSH key name
PrivateSubnet1CIDR:
default: Private subnet 1 CIDR
PrivateSubnet2CIDR:
default: Private subnet 2 CIDR
PrivateSubnet3CIDR:
default: Private subnet 3 CIDR
PublicSubnet1CIDR:
default: Public subnet 1 CIDR
PublicSubnet2CIDR:
default: Public subnet 2 CIDR
PublicSubnet3CIDR:
default: Public subnet 3 CIDR
QSS3BucketName:
default: Quick Start S3 bucket name
QSS3KeyPrefix:
default: Quick Start S3 key prefix
QSS3BucketRegion:
default: Quick Start S3 bucket region
RemoteAccessCIDR:
default: Allowed external access CIDR
VPCCIDR:
default: VPC CIDR
NodeInstanceType:
default: Nodes instance type
NumberOfNodes:
default: Number of nodes
MaxNumberOfNodes:
default: Maximum number of nodes
NodeGroupName:
default: Node group name
NodeVolumeSize:
default: Node volume size
ManagedNodeGroup:
default: Managed node group
ManagedNodeGroupAMIType:
default: Managed node group AMI type
AdditionalEKSAdminArns:
default: Additional EKS admin ARNs
KubernetesVersion:
default: Kubernetes version
LambdaZipsBucketName:
default: Lambda zips bucket name
ClusterAutoScaler:
default: Cluster autoscaler
EfsStorageClass:
default: EFS storage class
EfsPerformanceMode:
default: EFS performance mode
EfsThroughputMode:
default: EFS throughput mode
EfsProvisionedThroughputInMibps:
default: EFS provisioned throughput in Mibps
MonitoringStack:
default: Monitoring Stack
NumberOfAZs:
default: Number of Availability Zones
ProvisionBastionHost:
default: Provision Bastion Host
Parameters:
AvailabilityZones:
Description: The list of Availability Zones to use for the subnets in the VPC. Three
Availability Zones are used for this deployment, and the logical order of your
selections is preserved.
Type: List<AWS::EC2::AvailabilityZone::Name>
KeyPairName:
Description: The name of an existing public/private key pair, which allows you
to securely connect to your instance after it launches
Type: AWS::EC2::KeyPair::KeyName
PrivateSubnet1CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.0.0/19
Description: The CIDR block for private subnet 1 located in Availability Zone 1
Type: String
PrivateSubnet2CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.32.0/19
Description: The CIDR block for private subnet 2 located in Availability Zone 2
Type: String
PrivateSubnet3CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.64.0/19
Description: The CIDR block for private subnet 3 located in Availability Zone 3
Type: String
PublicSubnet1CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.128.0/20
Description: CIDR block for the public (DMZ) subnet 1 located in Availability
Zone 1
Type: String
PublicSubnet2CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.144.0/20
Description: The CIDR block for the public (DMZ) subnet 2 located in Availability
Zone 2
Type: String
PublicSubnet3CIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.160.0/20
Description: The CIDR block for the public (DMZ) subnet 3 located in Availability
Zone 3
Type: String
QSS3BucketName:
AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$
ConstraintDescription: Quick Start bucket name can include numbers, lowercase
letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen
(-).
Default: aws-quickstart
Description: S3 bucket name for the Quick Start assets. This string can include
numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start
or end with a hyphen (-).
Type: String
QSS3KeyPrefix:
AllowedPattern: ^[0-9a-zA-Z-/.]*$
ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters,
uppercase letters, hyphens (-), dots(.) and forward slash (/).
Default: quickstart-amazon-eks/
Description: S3 key prefix for the Quick Start assets. Quick Start key prefix
can include numbers, lowercase letters, uppercase letters, hyphens (-), dots(.) and
forward slash (/).
Type: String
QSS3BucketRegion:
Default: 'us-east-1'
Description: The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is
hosted. When using your own bucket, you must specify this value.
Type: String
RemoteAccessCIDR:
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]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x
Description: The CIDR IP range that is permitted to access the instances. We recommend
that you set this value to a trusted IP range.
Type: String
VPCCIDR:
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])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 10.0.0.0/16
Description: The CIDR block for the VPC
Type: String
AdditionalEKSAdminArns:
Default: ""
Description: "[OPTIONAL] Comma separated list of IAM user/role Amazon Resource Names (ARNs) to be granted admin access to the EKS cluster"
Type: CommaDelimitedList
NodeInstanceType:
Default: t3.medium
AllowedValues:
- t2.small
- t2.medium
- t2.large
- t2.xlarge
- t2.2xlarge
- t3.nano
- t3.micro
- t3.small
- t3.medium
- t3.large
- t3.xlarge
- t3.2xlarge
- m3.medium
- m3.large
- m3.xlarge
- m3.2xlarge
- m4.large
- m4.xlarge
- m4.2xlarge
- m4.4xlarge
- m4.10xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.12xlarge
- m5.24xlarge
- c4.large
- c4.xlarge
- c4.2xlarge
- c4.4xlarge
- c4.8xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.18xlarge
- i3.large
- i3.xlarge
- i3.2xlarge
- i3.4xlarge
- i3.8xlarge
- i3.16xlarge
- r3.xlarge
- r3.2xlarge
- r3.4xlarge
- r3.8xlarge
- r4.large
- r4.xlarge
- r4.2xlarge
- r4.4xlarge
- r4.8xlarge
- r4.16xlarge
- x1.16xlarge
- x1.32xlarge
- p2.xlarge
- p2.8xlarge
- p2.16xlarge
- p3.2xlarge
- p3.8xlarge
- p3.16xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.12xlarge
- r5.24xlarge
- r5d.large
- r5d.xlarge
- r5d.2xlarge
- r5d.4xlarge
- r5d.12xlarge
- r5d.24xlarge
- z1d.large
- z1d.xlarge
- z1d.2xlarge
- z1d.3xlarge
- z1d.6xlarge
- z1d.12xlarge
ConstraintDescription: Must be a valid EC2 instance type
Description: The type of EC2 instance for the node instances.
Type: String
NumberOfNodes:
Default: 3
Description: The number of Amazon EKS node instances. The default is one for each of the three Availability Zones.
Type: Number
MaxNumberOfNodes:
Default: 3
Description: The maximum number of Amazon EKS node instances. The default is three node.
Type: Number
NodeGroupName:
Default: Default
Description: The name for EKS node group.
Type: String
NodeVolumeSize:
Default: 20
Description: "The size for the node's root EBS volumes."
Type: String
ManagedNodeGroup:
AllowedValues: [ "yes", "no" ]
Default: "no"
Description: Choose if you want to use a managed node group. If you select "yes", you must select Kubernetes Version 1.14 or higher.
Type: String
ManagedNodeGroupAMIType:
Description: Select one of the two AMI types for your managed node group (only applies if you chose "yes" for ManagedNodeGroup). GPU instance types should use the AL2_x86_64_GPU AMI type, which uses the Amazon EKS-optimized Linux AMI with GPU support. Non-GPU instances should use the AL2_x86_64 AMI type, which uses the Amazon EKS-optimized Linux AMI.
AllowedValues: [ "AL2_x86_64", "AL2_x86_64_GPU", ""]
Default: "AL2_x86_64"
Type: String
KubernetesVersion:
Type: String
AllowedValues: [ "1.13", "1.14", "1.15" ]
Default: "1.15"
Description: The Kubernetes control plane version.
LambdaZipsBucketName:
Description: '[OPTIONAL] The name of the S3 bucket where the Lambda zip files should be placed. If you leave this parameter blank, an S3 bucket will be created.'
Type: String
Default: ''
ClusterAutoScaler:
Type: String
AllowedValues: [ Enabled, Disabled ]
Default: Disabled
Description: Choose Enabled to enable Kubernetes cluster autoscaler.
EfsStorageClass:
Type: String
AllowedValues: [ Enabled, Disabled ]
Default: Disabled
Description: Choose Enabled to enable EFS storage class, which will create the required EFS volume.
EfsPerformanceMode:
Type: String
AllowedValues: [ generalPurpose, maxIO ]
Default: generalPurpose
Description: Choose maxIO mode to provide greater IOPS with an increased latency. Only has an effect when EfsStorageClass is enabled.
EfsThroughputMode:
Type: String
AllowedValues: [ bursting, provisioned ]
Default: bursting
Description: Choose provisioned for throughput that is not dependent on the amount of data stored in the file system. Only has an effect when EfsStorageClass is enabled.
EfsProvisionedThroughputInMibps:
Type: Number
MinValue: 0
Default: 0
Description: Set to 0 if EfsThroughputMode is set to bursting. Only has an effect when EfsStorageClass is enabled.
MonitoringStack:
Type: String
AllowedValues: [ "Prometheus + Grafana", "None" ]
Default: "None"
Description: Enable Monitoring stack with "Prometheus+Grafana"
NumberOfAZs:
Type: String
AllowedValues: ["2", "3"]
Default: "3"
Description: Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter.
ProvisionBastionHost:
Type: String
AllowedValues: [ "Enabled", "Disabled" ]
Default: "Enabled"
Description: "Skip creating a bastion host by setting this is set to Disabled."
Rules:
EKSSupport:
Assertions:
- AssertDescription: Your AWS Region does *NOT* yet support Amazon EKS
Assert: !Contains
- - us-west-2
- us-east-1
- us-east-2
- sa-east-1
- eu-west-1
- eu-west-2
- eu-west-3
- eu-north-1
- eu-central-1
- ap-southeast-1
- ap-southeast-2
- ap-northeast-1
- ap-northeast-2
- ap-south-1
- ca-central-1
- !Ref 'AWS::Region'
EKSVersion_ManagedNodeGroup:
RuleCondition: !Equals [ !Ref 'ManagedNodeGroup', 'yes' ]
Assertions:
- AssertDescription: To use Managed Node Groups you must use EKS version 1.14 or higher
Assert: !Contains
- [ '1.15', '1.14' ]
- !Ref 'KubernetesVersion'
ClusterAutoScalerVerification:
RuleCondition: !Equals [ !Ref 'ManagedNodeGroup', 'yes' ]
Assertions:
- AssertDescription: To use Cluster AutoScaler you should not use Managed Node Groups
Assert: !Contains
- - 'Disabled'
- !Ref 'ClusterAutoScaler'
Conditions:
3AZDeployment: !Equals [!Ref NumberOfAZs, "3"]
2AZDeployment: !Or
- !Equals [!Ref NumberOfAZs, "2"]
- !Equals [!Ref NumberOfAZs, "3"]
UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart']
Resources:
VPCStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub
- 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template'
- S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
Parameters:
AvailabilityZones: !Join [ ',', !Ref 'AvailabilityZones' ]
KeyPairName: !Ref 'KeyPairName'
NumberOfAZs: !Ref 'NumberOfAZs'
PrivateSubnet1ACIDR: !Ref 'PrivateSubnet1CIDR'
PrivateSubnet2ACIDR: !Ref 'PrivateSubnet2CIDR'
PrivateSubnet3ACIDR: !Ref 'PrivateSubnet3CIDR'
PrivateSubnetATag2: "kubernetes.io/role/internal-elb="
PublicSubnet1CIDR: !Ref 'PublicSubnet1CIDR'
PublicSubnet2CIDR: !Ref 'PublicSubnet2CIDR'
PublicSubnet3CIDR: !Ref 'PublicSubnet3CIDR'
PublicSubnetTag2: "kubernetes.io/role/elb="
VPCCIDR: !Ref 'VPCCIDR'
EKSStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub
- 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/amazon-eks.template.yaml'
- S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
Parameters:
PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID
PublicSubnet2ID: !If
- 2AZDeployment
- !GetAtt VPCStack.Outputs.PublicSubnet2ID
- !Ref AWS::NoValue
PublicSubnet3ID: !If
- 3AZDeployment
- !GetAtt VPCStack.Outputs.PublicSubnet3ID
- !Ref AWS::NoValue
KeyPairName: !Ref KeyPairName
QSS3BucketName: !Ref QSS3BucketName
QSS3KeyPrefix: !Ref QSS3KeyPrefix
QSS3BucketRegion: !Ref QSS3BucketRegion
PrivateSubnet1ID: !GetAtt VPCStack.Outputs.PrivateSubnet1AID
PrivateSubnet2ID: !If
- 2AZDeployment
- !GetAtt VPCStack.Outputs.PrivateSubnet2AID
- !Ref AWS::NoValue
PrivateSubnet3ID: !If
- 3AZDeployment
- !GetAtt VPCStack.Outputs.PrivateSubnet3AID
- !Ref AWS::NoValue
NumberOfNodes: !Ref NumberOfNodes
MaxNumberOfNodes: !Ref MaxNumberOfNodes
NodeGroupName: !Ref NodeGroupName
NodeVolumeSize: !Ref NodeVolumeSize
ManagedNodeGroup: !Ref ManagedNodeGroup
ManagedNodeGroupAMIType: !Ref ManagedNodeGroupAMIType
LambdaZipsBucketName: !Ref LambdaZipsBucketName
NodeInstanceType: !Ref NodeInstanceType
RemoteAccessCIDR: !Ref RemoteAccessCIDR
AdditionalEKSAdminArns: !Join [ ",", !Ref AdditionalEKSAdminArns ]
VPCID: !GetAtt VPCStack.Outputs.VPCID
KubernetesVersion: !Ref KubernetesVersion
ProvisionClusterAutoScaler: !Ref ClusterAutoScaler
EfsStorageClass: !Ref EfsStorageClass
EfsPerformanceMode: !Ref EfsPerformanceMode
EfsThroughputMode: !Ref EfsThroughputMode
EfsProvisionedThroughputInMibps: !Ref EfsProvisionedThroughputInMibps
ProvisionMonitoringStack: !Ref MonitoringStack
ProvisionBastionHost: !Ref ProvisionBastionHost
Outputs:
KubeConfigPath:
Value: !GetAtt EKSStack.Outputs.KubeConfigPath
HelmLambdaArn:
Value: !GetAtt EKSStack.Outputs.HelmLambdaArn
KubeManifestLambdaArn:
Value: !GetAtt EKSStack.Outputs.KubeManifestLambdaArn
KubeGetLambdaArn:
Value: !GetAtt EKSStack.Outputs.KubeGetLambdaArn
EKSClusterName:
Value: !GetAtt EKSStack.Outputs.EKSClusterName
BastionIP:
Value: !GetAtt EKSStack.Outputs.BastionIP
BastionSecurityGroup:
Value: !GetAtt EKSStack.Outputs.BastionSecurityGroup
NodeGroupSecurityGroup:
Value: !GetAtt EKSStack.Outputs.NodeGroupSecurityGroup
I created also an IAM user to access my cluster whith this ARN : arn:aws:iam::XXXXXXXXXXXX:role/testrole
In order to access my cluster with this role aws suggested to update the config map aws-auth and to add something like this :
$ kubectl edit configmap aws-auth -n kube-system
mapRoles: |
- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testrole
username: testrole
groups:
- system:masters
link od recommandation here : https://aws.amazon.com/fr/premiumsupport/knowledge-center/eks-api-server-unauthorized-error/
Each day, when I leave work I have to delete my cluster and recreate it on monday (because of control plane cost). But I don't want each day, when I create my cluster with my cloud dormation template, to update manually my config map aws-auth to add the previous code.
How could I add this role in my cloudfourmation template in order to create my cluster with this default role added automatically ?
Thanks in advance
During the creation of the cluster with the template, there is a step asking you to add additionnal arn. You can specify here your arn then it will be added by default in your cluster automatically. You can set also this in your cloud formation file under :
AdditionalEKSAdminArns:
default: Additional EKS admin ARNs
I am trying to deploy Tableau to the AWS gov-cloud and I made some edits to the template in order to make it ready for govCloud deployment, however when I upload my YAML file to AWS I keep getting the following error:
Template error: if specifying one argument to Fn::GetAtt, that argument must be a non-empty string in format <LogicalId>.<Attribute>
I didn't edit any of the !GetAtt stuff from the template and the template doesn't seem to follow that order so I'm confused as to why I would keep getting this error on upload. Below is my YAML file snippet I would isolate the error but really not sure what part is causing the issue.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS CloudFormation Template: Single-node Tableau Server running on Windows,
CentOS, or Ubuntu. (qs-1puphiil4)'
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: AWS Environment and Machine Configuration
Parameters:
- KeyPairName
- AvailabilityZones
- VPCCIDR
- PublicSubnet1CIDR
- PublicSubnet2CIDR
- SourceCIDR
- InstanceType
- AMIOS
- Label:
default: Secrets
Parameters:
- Username
- Password
- TableauServerAdminUser
- TableauServerAdminPassword
- Label:
default: Registration
Parameters:
- AcceptEULA
- TableauServerLicenseKey
- RegFirstName
- RegLastName
- RegEmail
- RegCompany
- RegTitle
- RegDepartment
- RegIndustry
- RegPhone
- RegCity
- RegState
- RegZip
- RegCountry
- Label:
default: AWS Quick Start Configuration
Parameters:
- QSS3BucketName
- QSS3KeyPrefix
ParameterLabels:
AcceptEULA:
default: Accept Tableau End User License Agreement
AvailabilityZones:
default: Availability Zones
AMIOS:
default: AMI Operating System
InstanceType:
default: Tableau Amazon EC2 instance type
KeyPairName:
default: Key Pair Name
Password:
default: Tableau Services Manager (TSM) administrator password
PublicSubnet1CIDR:
default: Public Subnet 1 CIDR
PublicSubnet2CIDR:
default: Public Subnet 2 CIDR
QSS3BucketName:
default: Quick Start S3 Bucket Name
QSS3KeyPrefix:
default: Quick Start S3 Key Prefix
RegCity:
default: City
RegCompany:
default: Company
RegCountry:
default: Country
RegDepartment:
default: Department
RegEmail:
default: Email Address
RegFirstName:
default: First Name
RegIndustry:
default: Industry
RegLastName:
default: Last Name
RegPhone:
default: Phone
RegState:
default: State
RegTitle:
default: Title
RegZip:
default: Zip/Postal Code
SourceCIDR:
default: Source CIDR for Access
TableauServerAdminPassword:
default: Tableau Server administrator password
TableauServerAdminUser:
default: Tableau Server administrator username
TableauServerLicenseKey:
default: Tableau Activation Key
Username:
default: Tableau Services Manager (TSM) administrator username
VPCCR:
default: VPC CIDR
Parameters:
AvailabilityZones:
Description: 'List of Availability Zones to use for the subnets in teh VPC, Note: The logical order is preseved and 2 AZs will be used for this deployment'
Type: List<AWS::EC2::AvailabilityZone::Name>
AMIOS:
AllowedValues:
- Windows
- CentOS-7-HVM
- Ubuntu-Server-16.04-LTS-HVM
Default: Ubuntu-Server-16.04-LTS-HVM
Description: Operating System on which Tableau Server will be deployed
Type: String
AcceptEULA:
AllowedPattern: 'yes'
AllowedValues:
- 'yes'
- 'No'
Description: 'View the EULA at the Link: https://www.tableau.com/eula'
Type: String
InstanceType:
AllowedValues:
- m4.2xlarge
- m4.4xlarge
- m4.10xlarge
- m5.4xlarge
- m5.12xlarge
- c5.4xlarge
- c4.4xlarge
- c5d.4xlarge
- r5d.4xlarge
ConstraintDescription: must be a valid EC2 instance type.
Default: m5.4xlarge
Description: Amazon EC2 instance type
Type: String
KeyPairName:
ConstraintDescription: must be the name of an existing EC2 KeyPair.
Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
Type: AWS::EC2::KeyPair::KeyName
Password:
Description: Tableau Services Manager (TSM) administrator password
NoEcho: 'true'
Type: String
PublicSubnet1CIDR:
AllowedPattern: '[a-zA-Z0-9]+\..+'
Default: 10.0.128.0/20
Description: CIDR Block for the Public DMZ Subnet located in AZ1
Type: String
PublicSubnet2CIDR:
AllowedPattern: '[a-zA-Z0-9]+\..+'
Default: 10.0.144.0/20
Description: CIDR Block for the Public DMZ Subnet located in AZ2
Type: String
QSS3BucketName:
AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$
ConstraintDescription: Quick Start bucket name can include numbers, lowercase
letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen
(-).
Default: aws-quickstart
Description: S3 bucket name for the Quick Start assets. This string can include
numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start
or end with a hyphen (-).
Type: String
QSS3KeyPrefix:
AllowedPattern: ^[0-9a-zA-Z-/]*$
ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters,
uppercase letters, hyphens (-), and forward slash (/).
Default: quickstart-tableau-server/
Description: S3 key prefix for the Quick Start assets. Quick Start key prefix
can include numbers, lowercase letters, uppercase letters, hyphens (-), and
forward slash (/).
Type: String
RegCity:
Description: City
Type: String
RegCompany:
Description: Company
Type: String
RegCountry:
Description: Country
Type: String
RegDepartment:
Description: Department
Type: String
RegEmail:
Description: Email
MinLength: '1'
Type: String
RegFirstName:
Description: First Name
MinLength: '1'
Type: String
RegIndustry:
Description: Industry
Type: String
RegLastName:
Description: Last Name
MinLength: '1'
Type: String
RegPhone:
Description: Phone
Type: String
RegState:
Description: State
Type: String
RegTitle:
Description: Title
Type: String
RegZip:
Description: ZIP/Postal Code
Type: String
SourceCIDR:
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]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x
Description: The CIDR address from which you will connect to the instance
Type: String
TableauServerAdminPassword:
Description: The password of the initial administrator for Tableau Server
MinLength: '1'
NoEcho: 'true'
Type: String
TableauServerAdminUser:
Description: The name of the initial administrator for Tableau Server
MinLength: '1'
Type: String
TableauServerLicenseKey:
Description: License Key (leave blank for trial)
Type: String
Username:
AllowedPattern: ^(?!(tableau|tsmagent|admin|root)$)[A-Za-z0-9]*$
Description: Tableau Services Manager (TSM) administrator username (cannot be
'tableau' or 'tsmagent' or 'admin' or 'root')
MaxLength: '30'
Type: String
VPCCIDR:
AllowedPattern: '[a-zA-Z0-9]+\..+'
Default: 10.0.0.0/16
Description: CIDR Block for the VPC
Type: String
Conditions:
InfaOnWindows: !Equals
- !Ref 'AMIOS'
- Windows
InfaOnCentos: !Equals
- !Ref 'AMIOS'
- CentOS-7-HVM
Resources:
VPCStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws-us-gov.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template'
Parameters:
AvailabilityZones: !Join
- ','
- !Ref 'AvailabilityZones'
KeyPairName: !Ref 'KeyPairName'
NATInstanceType: t2.small
NumberOfAZs: '2'
PublicSubnet1CIDR: !Ref 'PublicSubnet1CIDR'
PublicSubnet2CIDR: !Ref 'PublicSubnet2CIDR'
CreatePrivateSubnets: 'false'
VPCCIDR: !Ref VPCCIDR
TableauIAMRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws-us-gov:iam::aws:policy/service-role/AmazonEC2RoleforSSM
Policies:
- PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- s3:GetObject
Resource:
- !Sub 'arn:aws-us-gov:s3:::${QSS3BucketName}/${QSS3KeyPrefix}*'
Effect: Allow
PolicyName: aws-quick-start-s3-policy
TableauServerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref 'TableauIAMRole'
WorkloadStack:
Type: AWS::CloudFormation::Stack
DependsOn: VPCStack
Properties:
TemplateURL: !Sub
- https://${QSS3BucketName}.s3.amazonaws-us-gov.com/${QSS3KeyPrefix}templates/${QSTableauWorkloadTemplate}
- QSTableauWorkloadTemplate: !If
- InfaOnWindows
- tableau-single-server-windows.template
- !If
- InfaOnCentos
- tableau-single-server-centos.template
- tableau-single-server-ubuntu.template
Parameters:
AMIOS: !Ref 'AMIOS'
PublicSubnetId: !Ref 'VPCStack.Outputs.PublicSubnet1ID'
AcceptEULA: !Ref 'AcceptEULA'
InstanceType: !Ref 'InstanceType'
KeyPairName: !Ref 'KeyPairName'
Password: !Ref 'Password'
QSS3BucketName: !Ref 'QSS3BucketName'
QSS3KeyPrefix: !Ref 'QSS3KeyPrefix'
RegCity: !Ref 'RegCity'
RegCompany: !Ref 'RegCompany'
RegCountry: !Ref 'RegCountry'
RegDepartment: !Ref 'RegDepartment'
RegEmail: !Ref 'RegEmail'
RegFirstName: !Ref 'RegFirstName'
RegIndustry: !Ref 'RegIndustry'
RegLastName: !Ref 'RegLastName'
RegPhone: !Ref 'RegPhone'
RegState: !Ref 'RegState'
RegTitle: !Ref 'RegTitle'
RegZip: !Ref 'RegZip'
SourceCIDR: !Ref 'SourceCIDR'
TableauServerAdminPassword: !Ref 'TableauServerAdminPassword'
TableauServerAdminUser: !Ref 'TableauServerAdminUser'
TableauServerLicenseKey: !Ref 'TableauServerLicenseKey'
Username: !Ref 'Username'
VPCId: !GetAtt 'VPCID'
Outputs:
VPCID:
Description: VPC ID
Value: !GetAtt 'VPCStack.Outputs.VPCID'
InstanceID:
Description: EC2 InstanceID of the instance running Tableau Server
Value: !GetAtt 'WorkloadStack.Outputs.InstanceID'
PublicIPAddress:
Description: Public IP Address of instance running Tableau Server
Value: !GetAtt 'WorkloadStack.Outputs.PublicIPAddress'
TableauServicesManagerURL:
Description: URL for the TSM Web UI
Value: !GetAtt 'WorkloadStack.Outputs.TableauServicesManagerURL'
TableauServerURL:
Description: URL for the Tableau Server
Value: !GetAtt 'WorkloadStack.Outputs.TableauServerURL'
The CloudFormation Linter will also catch these errors faster with more informative messages like:
E1010 Invalid GetAtt for Resources/WorkloadStack/Properties/Parameters/VPCId/Fn::GetAtt
template.yaml:333:9
so we know the issue is with line 333:
VPCId: !GetAtt 'VPCID'
The Visual Studio Code extension can also highlight these inline in your templates:
AWS::CloudFormation::Stack return values
Fn::GetAtt documentation
It looks like this line has been updated in the source repository, but I'd recommend opening a Github issue there if you're still experiencing difficulties with their templates
I created the following CloudFormation Template to kick up an ElasticSearch Domain. I want to use EXISTING VPC and Subnets, however, when I went through and modified this to do that, I get an error when standing up the stack that states:
"Property VpcId cannot be empty."
Yet, in the template parameters, you select the VpcId...
AWSTemplateFormatVersion: 2010-09-09
Description: >-
**NOTE** In order to create Elastisearch Domain in AWS using CloudFormation
verify you have the following Service Role created in IAM!!
-- AWSServiceRoleForAmazonElasticsearchService --
If you do not have this Role, create it using the following CLi Command --
aws iam create-service-linked-role --aws-service-name es.amazonaws.com
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "Configure Cluster"
Parameters:
- DomainName
- ElasticsearchVersion
- ZoneAwareness
-
Label:
default: "Data Instances"
Parameters:
- InstanceType
- DataInstanceCount
-
Label:
default: "Dedicated Master Instances"
Parameters:
- DedicatedMaster
- MasterInstanceType
- MasterInstanceCount
-
Label:
default: "Storage Config"
Parameters:
- StorageSize
-
Label:
default: "Network Config"
Parameters:
- VpcId
- SubNet1
- SubNet2
- AvailabilityZone
- AvailabilityZone2
- SecurityGroup
- GroupDescription
-
Label:
default: "IAM User Restriction Policy"
Parameters:
- IamUserArn
ParameterLabels:
DomainName:
default: "Name of the ElasticSearch Domain (lowecase, no spaces) - If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the domain name"
ElasticsearchVersion:
default: "Select the ElasticSearch version desired"
InstanceType:
default: "Instance Size of Data Instances"
DataInstanceCount:
default: "Number of Data Instances Required"
DedicatedMaster:
default: "Select if a Dedicated Master Instance is required"
MasterInstanceType:
default: "Instance Size of Master Instances"
MasterInstanceCount:
default: "How many Dedicated Master Instances are needed? (0, 3 or 5)"
StorageSize:
default: "Storage Size in GB"
VpcId:
default: "Select the VPC to deploy into (must already exist)"
SubNet1:
default: "Select the First Subnet"
SubNet2:
default: "Select the Second Subnet"
GroupDescription:
default: "New Security Group Description"
SecurityGroup:
default: "Name of the New Security Group"
IamUserArn:
default: "Enter the ARN for the IAM User to give initial access to the stack"
ZoneAwareness:
default: "Enable Zone Awareness (Availability Zone Replication) (recommended)"
Parameters:
DomainName:
Type: String
Default: "elasticsearchstack-cf"
MaxLength: '128'
ConstraintDescription: "Must be lowercase, numbers/letters and/or a dash"
ElasticsearchVersion:
Type: String
Default: 7.1
AllowedValues: [7.1, 6.8, 6.7, 6.6, 6.5] # Remove this line for free-form number entry
InstanceType:
Type: String
Default: t2.medium.elasticsearch
AllowedValues: [t2.small.elasticsearch, t2.medium.elasticsearch,
c4.large.elasticsearch, c4.xlarge.elasticsearch, c4.2xlarge.elasticsearch, c4.4xlarge.elasticsearch, c4.8xlarge.elasticsearch,
c5.large.elasticsearch, c5.xlarge.elasticsearch, c5.2xlarge.elasticsearch, c5.4xlarge.elasticsearch, c5.9xlarge.elasticsearch, c5.18xlarge.elasticsearch,
m3.medium.elasticsearch, m3.large.elasticsearch, m3.xlarge.elasticsearch, m3.2xlarge.elasticsearch,
m4.large.elasticsearch, m4.xlarge.elasticsearch, m4.2xlarge.elasticsearch, m4.4xlarge.elasticsearch, m4.10xlarge.elasticsearch,
m5.large.elasticsearch, m5.xlarge.elasticsearch, m5.2xlarge.elasticsearch, m5.4xlarge.elasticsearch, m5.12xlarge.elasticsearch,
r3.large.elasticsearch, r3.xlarge.elasticsearch, r3.2xlarge.elasticsearch, r3.4xlarge.elasticsearch, r3.8xlarge.elasticsearch,
r4.large.elasticsearch, r4.xlarge.elasticsearch, r4.2xlarge.elasticsearch, r4.4xlarge.elasticsearch, r4.16xlarge.elasticsearch,
r5.large.elasticsearch, r5.xlarge.elasticsearch, r5.2xlarge.elasticsearch, r5.4xlarge.elasticsearch, r5.12xlarge.elasticsearch,
i2.xlarge.elasticsearch, i2.2xlarge.elasticsearch,
i3.large.elasticsearch, i3.xlarge.elasticsearch, i3.2xlarge.elasticsearch, i3.4xlarge.elasticsearch, i3.8xlarge.elasticsearch, i3.16xlarge.elasticsearch]
ConstraintDescription: "Must be a valid EC2 Elasticsearch instance type."
DataInstanceCount:
Type: Number
Default: 2
AllowedValues: [2, 4, 6, 8, 10] # Remove this line for free-form number entry
MasterInstanceType:
Type: String
Default: t2.medium.elasticsearch
AllowedValues: [t2.small.elasticsearch, t2.medium.elasticsearch,
c4.large.elasticsearch, c4.xlarge.elasticsearch, c4.2xlarge.elasticsearch, c4.4xlarge.elasticsearch, c4.8xlarge.elasticsearch,
c5.large.elasticsearch, c5.xlarge.elasticsearch, c5.2xlarge.elasticsearch, c5.4xlarge.elasticsearch, c5.9xlarge.elasticsearch, c5.18xlarge.elasticsearch,
m3.medium.elasticsearch, m3.large.elasticsearch, m3.xlarge.elasticsearch, m3.2xlarge.elasticsearch,
m4.large.elasticsearch, m4.xlarge.elasticsearch, m4.2xlarge.elasticsearch, m4.4xlarge.elasticsearch, m4.10xlarge.elasticsearch,
m5.large.elasticsearch, m5.xlarge.elasticsearch, m5.2xlarge.elasticsearch, m5.4xlarge.elasticsearch, m5.12xlarge.elasticsearch,
r3.large.elasticsearch, r3.xlarge.elasticsearch, r3.2xlarge.elasticsearch, r3.4xlarge.elasticsearch, r3.8xlarge.elasticsearch,
r4.large.elasticsearch, r4.xlarge.elasticsearch, r4.2xlarge.elasticsearch, r4.4xlarge.elasticsearch, r4.16xlarge.elasticsearch,
r5.large.elasticsearch, r5.xlarge.elasticsearch, r5.2xlarge.elasticsearch, r5.4xlarge.elasticsearch, r5.12xlarge.elasticsearch,
i2.xlarge.elasticsearch, i2.2xlarge.elasticsearch,
i3.large.elasticsearch, i3.xlarge.elasticsearch, i3.2xlarge.elasticsearch, i3.4xlarge.elasticsearch, i3.8xlarge.elasticsearch, i3.16xlarge.elasticsearch]
ConstraintDescription: "Must be a valid EC2 Elasticsearch instance type."
MasterInstanceCount:
Type: Number
Default: 0
AllowedValues: [0, 3, 5] # Remove this line for free-form number entry
VpcId:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Must be the VPC ID of an existing Virtual Private Cloud."
SubNet1:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Must be the Subnet ID of an existing Subnet."
SubNet2:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Must be the Subnet ID of an existing Subnet."
SecurityGroup:
Type: String
Default: "elasticsearchstack-nsg"
ConstraintDescription: "Must be lowercase, numbers/letters and/or a dash"
DedicatedMaster:
Description: True or False
Type: String
Default: False
AllowedValues:
- True
- False
StorageSize:
Type: Number
Default: 20
MinValue: 10 # Remove this line for free-form number entry (suggested to keep this line)
MaxValue: 1000 # Remove this line for free-form number entry
GroupDescription: # Security Group Description
Type: String
Default: "ElasticSearch Stack from CloudFormation"
MaxLength: '128'
ConstraintDescription: "Upper/Lowercase, numbers/letters and/or a dash"
IamUserArn:
Type: String
Default: "arn:aws:iam::<AccountNumber>:user/<username>"
ZoneAwareness:
Description: True or False
Type: String
Default: True
AllowedValues:
- True
- False
Conditions: # Checks to see if Dedicated Master is True
DedicatedMasterYes: !Equals [ !Ref DedicatedMaster, True]
Resources:
ElasticsearchDomain:
Type: AWS::Elasticsearch::Domain
Properties:
DomainName: !Ref DomainName
ElasticsearchVersion: !Ref ElasticsearchVersion
ElasticsearchClusterConfig:
DedicatedMasterEnabled: !Ref DedicatedMaster
InstanceCount: !Ref DataInstanceCount
ZoneAwarenessEnabled: !Ref ZoneAwareness
InstanceType: !Ref InstanceType
DedicatedMasterType: # If Dedicated Master is True, then use !Ref, if not, use NoValue (NULL)
!If [DedicatedMasterYes, !Ref MasterInstanceType, !Ref "AWS::NoValue"]
DedicatedMasterCount:
!If [DedicatedMasterYes, !Ref MasterInstanceCount, !Ref "AWS::NoValue"]
EBSOptions:
EBSEnabled: True
Iops: 0
VolumeSize: !Ref StorageSize
VolumeType: "gp2"
SnapshotOptions:
AutomatedSnapshotStartHour: "0"
AccessPolicies:
Version: 2012-10-17
Statement:
- Effect: Deny
Principal:
AWS: !Ref IamUserArn
Action: 'es:*'
Resource: "*"
AdvancedOptions: # BOTH of these settingsd are REQUIRED (regardless of what the documentation states) - Bug filed: https://forums.aws.amazon.com/thread.jspa?messageID=768527
rest.action.multi.allow_explicit_index: 'true'
indices.fielddata.cache.size: !Ref "AWS::NoValue"
VPCOptions:
VpcId: !Ref VpcId
SubnetIds:
- !Ref subnet1
- !Ref subnet2
SecurityGroupIds:
- !Ref mySecurityGroup
subnet1:
Type: AWS::EC2::Subnet
subnet2:
Type: AWS::EC2::Subnet
mySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VpcId
GroupName: !Ref SecurityGroup
GroupDescription: !Ref GroupDescription
SecurityGroupIngress:
- FromPort: '443'
IpProtocol: tcp
ToPort: '443'
CidrIp: 0.0.0.0/0
Outputs:
DomainArn:
Value: !GetAtt ElasticsearchDomain.DomainArn
DomainEndpoint:
Value: !GetAtt ElasticsearchDomain.DomainEndpoint
SecurityGroupId:
Value: !Ref mySecurityGroup
SubnetId:
Value: !Ref subnet1
SubnetId2:
Value: !Ref subnet2
I'm sure I am missing something simple, but my brain is fried. Thanks all!
#WarrenG - Thanks for that, I just managed to get that figured out too...
Here is the working, fixed template:
AWSTemplateFormatVersion: 2010-09-09
Description: >-
**NOTE** In order to create Elastisearch Domain in AWS using CloudFormation
verify you have the following Service Role created in IAM!!
-- AWSServiceRoleForAmazonElasticsearchService --
If you do not have this Role, create it using the following CLi Command --
aws iam create-service-linked-role --aws-service-name es.amazonaws.com
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "Configure Cluster"
Parameters:
- DomainName
- ElasticsearchVersion
- ZoneAwareness
- SnapShotHour
-
Label:
default: "Data Instances"
Parameters:
- InstanceType
- DataInstanceCount
-
Label:
default: "Dedicated Master Instances"
Parameters:
- DedicatedMaster
- MasterInstanceType
- MasterInstanceCount
-
Label:
default: "Storage Config"
Parameters:
- StorageSize
-
Label:
default: "Network Config"
Parameters:
- VpcId
- SubNet1
- SubNet2
- SecurityGroup
- GroupDescription
-
Label:
default: "IAM User Restriction Policy"
Parameters:
- IamUserArn
ParameterLabels:
DomainName:
default: "Name of the ElasticSearch Domain (lowecase, no spaces) - If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the domain name"
ElasticsearchVersion:
default: "Select the ElasticSearch version desired"
InstanceType:
default: "Instance Size of Data Instances"
DataInstanceCount:
default: "Number of Data Instances Required"
DedicatedMaster:
default: "Select if a Dedicated Master Instance is required"
MasterInstanceType:
default: "Instance Size of Master Instances"
MasterInstanceCount:
default: "How many Dedicated Master Instances are needed? (0, 3 or 5)"
StorageSize:
default: "Storage Size in GB"
VpcId:
default: "Select the VPC to deploy into (must already exist)"
SubNet1:
default: "Select the First Subnet"
SubNet2:
default: "Select the Second Subnet"
GroupDescription:
default: "New Security Group Description"
SecurityGroup:
default: "Name of the New Security Group"
IamUserArn:
default: "Enter the ARN for the IAM User to give initial access to the stack"
ZoneAwareness:
default: "Enable Zone Awareness (Availability Zone Replication) (recommended)"
SnapShotHour:
default: "Set the hour to run the Automated Snapshot (0-23) (Default: UTC Timezone)"
Parameters:
DomainName:
Type: String
Default: "elasticsearchstack-cf"
MaxLength: '128'
ConstraintDescription: "Must be lowercase, numbers/letters and/or a dash"
SnapShotHour:
Type: Number
Default: 0
MinValue: 0
MaxValue: 23
ElasticsearchVersion:
Type: String
Default: 7.1
AllowedValues: [7.1, 6.8, 6.7, 6.6, 6.5] # Remove this line for free-form number entry
InstanceType:
Type: String
Default: t2.medium.elasticsearch
AllowedValues: [t2.small.elasticsearch, t2.medium.elasticsearch,
c4.large.elasticsearch, c4.xlarge.elasticsearch, c4.2xlarge.elasticsearch, c4.4xlarge.elasticsearch, c4.8xlarge.elasticsearch,
c5.large.elasticsearch, c5.xlarge.elasticsearch, c5.2xlarge.elasticsearch, c5.4xlarge.elasticsearch, c5.9xlarge.elasticsearch, c5.18xlarge.elasticsearch,
m3.medium.elasticsearch, m3.large.elasticsearch, m3.xlarge.elasticsearch, m3.2xlarge.elasticsearch,
m4.large.elasticsearch, m4.xlarge.elasticsearch, m4.2xlarge.elasticsearch, m4.4xlarge.elasticsearch, m4.10xlarge.elasticsearch,
m5.large.elasticsearch, m5.xlarge.elasticsearch, m5.2xlarge.elasticsearch, m5.4xlarge.elasticsearch, m5.12xlarge.elasticsearch,
r3.large.elasticsearch, r3.xlarge.elasticsearch, r3.2xlarge.elasticsearch, r3.4xlarge.elasticsearch, r3.8xlarge.elasticsearch,
r4.large.elasticsearch, r4.xlarge.elasticsearch, r4.2xlarge.elasticsearch, r4.4xlarge.elasticsearch, r4.16xlarge.elasticsearch,
r5.large.elasticsearch, r5.xlarge.elasticsearch, r5.2xlarge.elasticsearch, r5.4xlarge.elasticsearch, r5.12xlarge.elasticsearch,
i2.xlarge.elasticsearch, i2.2xlarge.elasticsearch,
i3.large.elasticsearch, i3.xlarge.elasticsearch, i3.2xlarge.elasticsearch, i3.4xlarge.elasticsearch, i3.8xlarge.elasticsearch, i3.16xlarge.elasticsearch]
ConstraintDescription: "Must be a valid EC2 Elasticsearch instance type."
DataInstanceCount:
Type: Number
Default: 2
AllowedValues: [2, 4, 6, 8, 10] # Remove this line for free-form number entry
MasterInstanceType:
Type: String
Default: t2.medium.elasticsearch
AllowedValues: [t2.small.elasticsearch, t2.medium.elasticsearch,
c4.large.elasticsearch, c4.xlarge.elasticsearch, c4.2xlarge.elasticsearch, c4.4xlarge.elasticsearch, c4.8xlarge.elasticsearch,
c5.large.elasticsearch, c5.xlarge.elasticsearch, c5.2xlarge.elasticsearch, c5.4xlarge.elasticsearch, c5.9xlarge.elasticsearch, c5.18xlarge.elasticsearch,
m3.medium.elasticsearch, m3.large.elasticsearch, m3.xlarge.elasticsearch, m3.2xlarge.elasticsearch,
m4.large.elasticsearch, m4.xlarge.elasticsearch, m4.2xlarge.elasticsearch, m4.4xlarge.elasticsearch, m4.10xlarge.elasticsearch,
m5.large.elasticsearch, m5.xlarge.elasticsearch, m5.2xlarge.elasticsearch, m5.4xlarge.elasticsearch, m5.12xlarge.elasticsearch,
r3.large.elasticsearch, r3.xlarge.elasticsearch, r3.2xlarge.elasticsearch, r3.4xlarge.elasticsearch, r3.8xlarge.elasticsearch,
r4.large.elasticsearch, r4.xlarge.elasticsearch, r4.2xlarge.elasticsearch, r4.4xlarge.elasticsearch, r4.16xlarge.elasticsearch,
r5.large.elasticsearch, r5.xlarge.elasticsearch, r5.2xlarge.elasticsearch, r5.4xlarge.elasticsearch, r5.12xlarge.elasticsearch,
i2.xlarge.elasticsearch, i2.2xlarge.elasticsearch,
i3.large.elasticsearch, i3.xlarge.elasticsearch, i3.2xlarge.elasticsearch, i3.4xlarge.elasticsearch, i3.8xlarge.elasticsearch, i3.16xlarge.elasticsearch]
ConstraintDescription: "Must be a valid EC2 Elasticsearch instance type."
MasterInstanceCount:
Type: Number
Default: 0
AllowedValues: [0, 3, 5] # Remove this line for free-form number entry
VpcId:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Must be the VPC ID of an existing Virtual Private Cloud."
SubNet1:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Must be the Subnet ID of an existing Subnet."
SubNet2:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Must be the Subnet ID of an existing Subnet."
SecurityGroup:
Type: String
Default: "elasticsearchstack-nsg"
ConstraintDescription: "Must be lowercase, numbers/letters and/or a dash"
DedicatedMaster:
Description: True or False
Type: String
Default: False
AllowedValues:
- True
- False
StorageSize:
Type: Number
Default: 20
MinValue: 10 # Remove this line for free-form number entry (suggested to keep this line)
MaxValue: 1000 # Remove this line for free-form number entry
GroupDescription: # Security Group Description
Type: String
Default: "ElasticSearch Stack from CloudFormation"
MaxLength: '128'
ConstraintDescription: "Upper/Lowercase, numbers/letters and/or a dash"
IamUserArn:
Type: String
Default: "arn:aws:iam::<AccountNumber>:user/<username>"
ZoneAwareness:
Description: True or False
Type: String
Default: True
AllowedValues:
- True
- False
Conditions: # Checks to see if Dedicated Master is True
DedicatedMasterYes: !Equals [ !Ref DedicatedMaster, True]
Resources:
ElasticsearchDomain:
Type: AWS::Elasticsearch::Domain
Properties:
DomainName: !Ref DomainName
ElasticsearchVersion: !Ref ElasticsearchVersion
ElasticsearchClusterConfig:
DedicatedMasterEnabled: !Ref DedicatedMaster
InstanceCount: !Ref DataInstanceCount
ZoneAwarenessEnabled: !Ref ZoneAwareness
InstanceType: !Ref InstanceType
DedicatedMasterType: # If Dedicated Master is True, then use !Ref, if not, use NoValue (NULL)
!If [DedicatedMasterYes, !Ref MasterInstanceType, !Ref "AWS::NoValue"]
DedicatedMasterCount:
!If [DedicatedMasterYes, !Ref MasterInstanceCount, !Ref "AWS::NoValue"]
EBSOptions:
EBSEnabled: True
Iops: 0
VolumeSize: !Ref StorageSize
VolumeType: "gp2"
SnapshotOptions:
AutomatedSnapshotStartHour: !Ref SnapShotHour
AccessPolicies:
Version: 2012-10-17
Statement:
- Effect: Deny
Principal:
AWS: !Ref IamUserArn
Action: 'es:*'
Resource: "*"
AdvancedOptions: # BOTH of these settingsd are REQUIRED (regardless of what the documentation states) - Bug filed: https://forums.aws.amazon.com/thread.jspa?messageID=768527
rest.action.multi.allow_explicit_index: 'true'
indices.fielddata.cache.size: !Ref "AWS::NoValue"
VPCOptions:
SubnetIds:
- !Ref SubNet1
- !Ref SubNet2
SecurityGroupIds:
- !Ref mySecurityGroup
mySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VpcId
GroupName: !Ref SecurityGroup
GroupDescription: !Ref GroupDescription
SecurityGroupIngress:
- FromPort: '443'
IpProtocol: tcp
ToPort: '443'
CidrIp: 0.0.0.0/0
Outputs:
DomainArn:
Value: !GetAtt ElasticsearchDomain.DomainArn
DomainEndpoint:
Value: !GetAtt ElasticsearchDomain.DomainEndpoint
SecurityGroupId:
Value: !Ref mySecurityGroup