Skip to content
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
3 changes: 3 additions & 0 deletions docs/source/docs/providers/aws/instance-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ Read more: [Caching Docker Image on an EBS Volume].
```
It will open ports 6006 for TensorBoard and 8888 for Jupyter Notebook.

-__`inboundIp`__ _(optional)_ - an IP address or CIDR range to use as a whitelist for all ports provided
to the security group. The default is to not use a whitelist.

- __`localSshPort`__ _(optional)_ - if this parameter is set, all the Spotty commands will create SSH connections
with the instance using the IP address __127.0.0.1__ and the specified port. This can be useful in case when an
instance doesn't have a public IP address and a jump-server is used for tunneling.
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def get_description():
'cfn_flip', # to work with CloudFormation templates
'schema',
'chevron',
'netaddr' # validates configuration IP addresses
],
tests_require=['moto'],
test_suite='tests',
Expand Down
10 changes: 1 addition & 9 deletions spotty/providers/aws/cfn_templates/instance/data/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,7 @@ Resources:
IpProtocol: -1
FromPort: 0
ToPort: 65535
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 22
ToPort: 22
- CidrIpv6: ::/0
IpProtocol: tcp
FromPort: 22
ToPort: 22
SecurityGroupIngress: []

PreparingInstanceSignal:
Type: AWS::CloudFormation::WaitCondition
Expand Down
24 changes: 10 additions & 14 deletions spotty/providers/aws/cfn_templates/instance/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,16 @@ def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_comma
}]
del template['Resources']['InstanceLaunchTemplate']['Properties']['LaunchTemplateData']['SecurityGroupIds']

# add ports to the security group
for port in instance_config.ports:
if port != 22:
template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{
'CidrIp': '0.0.0.0/0',
'IpProtocol': 'tcp',
'FromPort': port,
'ToPort': port,
}, {
'CidrIpv6': '::/0',
'IpProtocol': 'tcp',
'FromPort': port,
'ToPort': port,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just noticed that now if the inboundIp parameter is not specified, we're not opening ports for IPv6. So, I think we need to use None for the default value instead of 0.0.0.0/0 to know when the parameter wasn't specified and open ports for both protocols.

}]
# add ports to the security group for the user-defined inbound IP
inbound_ip = instance_config.inbound_ip
cidr_ip = 'CidrIpv6' if inbound_ip.version == 6 else 'CidrIp'
for port in [22] + instance_config.ports:
template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{
cidr_ip: str(inbound_ip),
'IpProtocol': 'tcp',
'FromPort': port,
'ToPort': port,
}]

if instance_config.is_spot_instance:
# set maximum price
Expand Down
6 changes: 5 additions & 1 deletion spotty/providers/aws/config/instance_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ def max_price(self) -> float:
@property
def managed_policy_arns(self) -> list:
return self._params['managedPolicyArns']

@property
def instance_profile_arn(self) -> str:
return self._params['instanceProfileArn']

@property
def inbound_ip(self) -> str:
return self._params['inboundIp']
3 changes: 3 additions & 0 deletions spotty/providers/aws/config/validation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from schema import Schema, Optional, And, Regex, Or, Use
from netaddr import IPNetwork
from spotty.config.validation import validate_config, get_instance_parameters_schema, has_prefix


Expand Down Expand Up @@ -30,6 +31,8 @@ def validate_instance_parameters(params: dict):
),
Optional('managedPolicyArns', default=[]): [str],
Optional('instanceProfileArn', default=None): str,
Optional('inboundIp', default='0.0.0.0/0'): Use(IPNetwork, error='"inboundIp" should be a valid IP '

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For the default value, the inbound_ip.version == 6 check will fail later in the code as the Use(IPNetwork, ... function is not applied. It can be fixed with the IPNetwork('0.0.0.0/0') value, but as I mentioned in another comment, we need to use None instead to know when the value wasn't set at all.

'address or CIDR range'),
}

volumes_checks = [
Expand Down
1 change: 1 addition & 0 deletions tests/providers/aws/config/instance_config_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def test_default_configuration(self):
'spotInstance': False,
'subnetId': '',
'volumes': [],
'inboundIp': '0.0.0.0/0',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be fixed as well when the default inboundIp value is changed.

}

self.assertEqual(expected_params, validate_instance_parameters(required_params))
Expand Down