Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elasticsearch integration #114

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ jmeter.log
installer/*.log
security-check/*.log
saas-boost-install.log
samples
34 changes: 31 additions & 3 deletions resources/saas-boost-svc-onboarding.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Parameters:
ECSRepository:
Description: SaaS Boost ECR image repository
Type: String

Resources:
SSMParamOnboardingTemplate:
Type: AWS::SSM::Parameter
Expand Down Expand Up @@ -232,6 +233,13 @@ Resources:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
# # Elasticsearch policy
# - Effect: Allow
# Action:
# - es:DescribeElasticsearchDomain
# Resource:
# - !Sub arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/*/*

Comment on lines +236 to +242
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these commented out lines need to be here?

Policies:
- PolicyName: !Sub sb-${Environment}-onboarding-svc-policy-${AWS::Region}
PolicyDocument:
Expand Down Expand Up @@ -564,6 +572,16 @@ Resources:
- ec2:AuthorizeSecurityGroupEgress
Resource:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*
# Elasticsearch onboarding policy
- Effect: Allow
Action:
- es:AddTags
- es:CreateElasticsearchDomain
- es:DescribeElasticsearchDomain
- es:CreateElasticsearchServiceRole
Resource:
- !Sub arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In keeping with the principle of least privilege, it would be better if our Elasticsearch policies only gave us access to the domain managed by SaaS Boost, not all Elasticsearch domains in that region for that AWS account id.


OnboardingServiceDeleteTenantExecutionRole:
Type: AWS::IAM::Role
Properties:
Expand Down Expand Up @@ -875,6 +893,19 @@ Resources:
- ec2:RevokeSecurityGroupEgress
Resource:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*
# Elasticsearch onboarding delete policy
- Effect: Allow
Action:
- es:DeleteElasticsearchDomain
- es:DeleteElasticsearchServiceRole
- es:DescribeElasticsearchDomain
# case specific - debug purpose
# - es:ESHttpPut
##############
Comment on lines +902 to +904
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe in what cases this would be useful?

- es:RemoveTags
Resource:
- !Sub arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/*

OnboardingServiceGetAllLogs:
Type: AWS::Logs::LogGroup
Properties:
Expand Down Expand Up @@ -1200,9 +1231,6 @@ Resources:
Environment:
Variables:
ONBOARDING_TABLE: !Ref OnboardingTable
API_TRUST_ROLE: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
API_GATEWAY_HOST: !Sub ${SaaSBoostPrivateApi}.execute-api.${AWS::Region}.amazonaws.com
API_GATEWAY_STAGE: !Ref PrivateApiStage
Comment on lines -1203 to -1205
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables are used by the onboarding service to properly function. Have you tested a fresh SaaS Boost install with these changes?

Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down
177 changes: 177 additions & 0 deletions resources/tenant-onboarding-es.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@

# Copyright 2020 Daniel Cortez Stevenson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Original: https://gist.github.com/daniel-cortez-stevenson/
# modified: https://github.com/AffiTheCreator
#
---
AWSTemplateFormatVersion: 2010-09-09
Description: SaaS Boost Tenant Onboarding AWS Elasticsearch Service (ES)
Parameters:
TenantId:
Description: The GUID for the tenant
Type: String
VPC:
Description: VPC id for this tenant
Type: AWS::EC2::VPC::Id
# PrivateSubnetA:
# Description: Private subnet for ES
# Type: AWS::EC2::Subnet::Id
SubnetPublicA:
Description: Public subnet for ES
Type: AWS::EC2::Subnet::Id
# PrivateSubnetB:
# Description: Private subnet for EFS mount target
# Type: AWS::EC2::Subnet::Id
ECSSecurityGroup:
Description: Source security group for ECS to access EFS
Type: AWS::EC2::SecurityGroup::Id
CustomEndpointEnabled:
Type: String
AllowedValues: ['true', 'false']
Default: 'false'
EnforceHTTPS:
Type: String
AllowedValues: ['true', 'false']
Default: 'false'
ESPortHTTP:
Type: String
Default: '80'
ESPortHTTPS:
Type: String
Default: '443'
ESPort:
Type: String
Comment on lines +55 to +56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this parameter be removed? It doesn't appear to be used.

TLSSecurityPolicy:
Type: String
AllowedValues: ['true', 'false']
Default: 'false'
ElasticsearchName:
Description: The name of the AWS Elasticsearch Service deployment.
Type: String
ConstraintDescription: Must be a valid AWS ES domain name prefix. The name must start with a
lowercase letter and must be between 3 and 28 characters. Valid characters
are a-z (lowercase only), 0-9, and - (hyphen).
AllowedPattern: '[a-z][a-z0-9\\-]+'
ElasticsearchVersion:
Default: '6.2'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not choose the latest version?

Type: String
ConstraintDescription: Must be an allowed AWS ES version (Major.Minor)
AllowedValues: ['7.9', '7.8', '7.7', '7.4', '7.1', '6.8', '6.7', '6.5', '6.4', '6.3', '6.2', '6.0', '5.6', '5.5'] # aws es list-elasticsearch-versions --query "ElasticsearchVersions[]"
ElasticsearchDataInstanceType:
Description: Instance type for data nodes.
Type: String
Default: 'r5.2xlarge.elasticsearch'
NumberOfMasterNodes:
Description: How many dedicated master nodes you want to have. 3 is recommended.
Type: Number
Default: 3
NumberOfDataNodes:
Description: How many data nodes you want to have. Multiples of your number of availability zones (2) is recommended.
Type: Number
Default: '2'
MinValue: '1'
MaxValue: '20'
EBSEnabled:
Description: 'Specifies whether Amazon EBS volumes are attached to data nodes in the Amazon ES domain (some instance types come with instance store that you can use instead).'
Type: String
AllowedValues: ['true', 'false']
Default: 'true'
EBSVolumeSize:
Description: 'The size of the EBS volume for each data node. The minimum and maximum size of an EBS volume depends on the EBS volume type and the instance type to which it is attached.'
Type: Number
Default: '10'
Conditions:
EnforceHTTPS_false: !Equals [ !Ref "EnforceHTTPS", "false" ]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simplify this condition by just naming it ShouldEnforceHTTPS and checking that it's equal to true. Your results for checks against the condition just flip.


Resources:
ESSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName:
Fn::Join: ['', ['tenant-', !Select [0, !Split ['-', !Ref TenantId]], '-es-sg']]
GroupDescription: Elasticsearch Security Group
VpcId: !Ref VPC
ESSecurityGroupIngressECS:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref ESSecurityGroup
IpProtocol: tcp
# To review !!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what you mean by this comment?

FromPort: !If [EnforceHTTPS_false, !Ref ESPortHTTP, !Ref ESPortHTTPS]
ToPort: !If [EnforceHTTPS_false, !Ref ESPortHTTP, !Ref ESPortHTTPS]
SourceSecurityGroupId: !Ref ECSSecurityGroup

ElasticsearchDomain:
DependsOn: ESSecurityGroup
Type: AWS::Elasticsearch::Domain
Properties:
ElasticsearchVersion: !Ref ElasticsearchVersion
DomainName: !Ref ElasticsearchName
DomainEndpointOptions:
EnforceHTTPS: !Ref EnforceHTTPS
EBSOptions:
EBSEnabled: !Ref EBSEnabled
Iops: 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iops under EBSOptions means "The number of I/O operations per second (IOPS) that the volume supports. This property applies only to the Provisioned IOPS (SSD) EBS volume type. reference" It's also not required: why do we explicitly set it to 0 here?

VolumeSize: !Ref EBSVolumeSize
VolumeType: standard
ElasticsearchClusterConfig:
InstanceCount: !Ref NumberOfDataNodes
InstanceType: !Ref ElasticsearchDataInstanceType
ZoneAwarenessEnabled: false
AdvancedOptions:
rest.action.multi.allow_explicit_index: "true"
SnapshotOptions:
AutomatedSnapshotStartHour: 0
VPCOptions:
SubnetIds:
- !Ref SubnetPublicA
# - !Ref PrivateSubnetB
SecurityGroupIds:
- !Ref ESSecurityGroup
AccessPolicies:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: '*'
Action: "es:*"
Resource: !Sub "arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${ElasticsearchName}/*"
Comment on lines +147 to +151
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives every AWS logged in user permissions to enact any Elasticsearch operation on this Elasticsearch domain. This must be restricted down to at the very least the account running this SaaS Boost installation by default. Developers using Elasticsearch as part of their SaaS Boost installation can change this to accept a wider set of incoming traffic if needed, but we shouldn't endorse that by default.

Tags:
- Key: Tenant
Value: !Ref TenantId

Outputs:
Arn:
Value: !GetAtt ElasticsearchDomain.Arn
ESDomainArn:
Value: !GetAtt ElasticsearchDomain.DomainArn
ESDomainEndpoint:
Description: Elasticsearch endpoint
Value: !GetAtt ElasticsearchDomain.DomainEndpoint
ESClusterName:
Description: The Elasticsearch Cluster
Value: !Ref ElasticsearchName
ESClusterPort:
Description: Listening Port of Elasticsearch cluster
Value: !Ref ESPortHTTP
ESClusterPortDefault:
Description: Typicaly when migrating an on-premises elastricsearch(ES) stack to a cloud cluster the application that uses ES will need 2 ports, this bypasses such requirement
Value: !Ref ESPortHTTPS
# ESSubnetID:
# Description: VPC Subnet ID for Elasticsearch Cluster
# Value: !Ref PrivateSubnetA

...
Loading