You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An independent review of the custom-security-group feature (previous two
commits) found several real gaps. Fixed all of them:
- security_group was dropped when a run provisioned a new instance into an
existing fleet (only the fleet-apply path honored it). Fixed by threading
security_group through the Requirements pipeline exactly like reservation
already is (Requirements.security_group, combine_fleet_and_run_profiles/
combine_fleet_and_run_requirements, and sourcing run_job's
InstanceConfiguration from job.job_spec.requirements.security_group instead
of the run's raw profile).
- security_group was silently ignored when an offer resolved to a backend
that doesn't support it (e.g. GCP). offers.py now narrows backend_types to
BACKENDS_WITH_SECURITY_GROUP_SUPPORT when security_group is set, mirroring
the existing reservation filtering.
- AWS: the configurator forbade combining security_group_name with
security_group_ids, but compute.py implements (and docs/tests described) a
fallback from ids to name - the combination is now allowed. Also added
validation catching region-key typos in security_group_ids, and a clearer
ComputeError instead of a confusing NoCapacityError retry loop when a
configured security group doesn't exist in the target VPC.
- Azure: renamed network_security_group_ids to network_security_group_names
since the values are NSG names (not IDs) scoped to the backend's
resource_group, and added region-key typo validation.
- GCP: create_firewall_rules no longer disables the gateway firewall rule,
matching AWS/Azure/OCI where gateway security resources are always
auto-managed regardless of the custom-security-group settings.
- OCI: the shared subnet has no security_list_ids, so it inherits the VCN's
permissive default security list (SSH open to 0.0.0.0/0, allow-all egress).
Since OCI evaluates security lists and NSGs as a union of allows, a custom
NSG could not actually restrict anything. Fixed by routing custom-NSG
instances into a separate, dedicated VCN/subnet with no security list, so
the NSG becomes the sole security boundary. The default VCN/subnet used by
auto-managed-NSG instances is completely untouched. Also added region-key
typo validation and corrected the docs to accurately attribute default SSH
exposure to the security list, not the NSG.
Copy file name to clipboardExpand all lines: mkdocs/docs/concepts/backends.md
+32-12Lines changed: 32 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -489,7 +489,9 @@ There are two ways to configure Azure: using a client secret or using the defaul
489
489
By default, `dstack` creates and manages its own network security group (opening SSH to the internet
490
490
and allowing all traffic within the group so multi-node clusters work out of the box).
491
491
Azure NSG names must be unique within a resource group regardless of region, so a custom NSG is
492
-
configured per location via `network_security_group_ids`:
492
+
configured per location via `network_security_group_names`. The values are plain NSG names
493
+
within the configured `resource_group` (not full Azure resource IDs), so NSGs in a different
494
+
resource group cannot be referenced:
493
495
494
496
```yaml
495
497
projects:
@@ -499,12 +501,12 @@ There are two ways to configure Azure: using a client secret or using the defaul
499
501
creds:
500
502
type: default
501
503
regions: [westeurope, eastus]
502
-
network_security_group_ids:
504
+
network_security_group_names:
503
505
westeurope: my-network-security-group-we
504
506
eastus: my-network-security-group-eus
505
507
```
506
508
507
-
Locations not covered by `network_security_group_ids` fall back to dstack's auto-created network
509
+
Locations not covered by `network_security_group_names` fall back to dstack's auto-created network
508
510
security group. Either way, `dstack` attaches the network security group to instances as-is and
509
511
never adds, removes, or modifies its rules. You're responsible for SSH reachability and, for
510
512
multi-node clusters, for allowing traffic between instances in the group.
@@ -730,11 +732,11 @@ gcloud projects list --format="json(projectId)"
730
732
Additionally, [Cloud NAT](https://cloud.google.com/nat/docs/overview) must be configured to provide access to external resources for provisioned instances.
731
733
732
734
??? info "Custom firewall rules"
733
-
By default, `dstack` creates VPC firewall rules allowing inbound SSH (and, for gateways, HTTP/HTTPS) from
734
-
the internet, scoped to the `dstack-runner-instance`and `dstack-gateway-instance`target tags.
735
+
By default, `dstack` creates a VPC firewall rule allowing inbound SSH from the internet to instances,
736
+
scoped to the `dstack-runner-instance` target tag.
735
737
Unlike AWS/Azure/OCI, GCP firewall rules apply to the whole VPC rather than to a single attachable resource,
736
738
so there's no per-fleet override — if you manage your own firewall rules and don't want `dstack` creating
737
-
rules that open ports to `0.0.0.0/0`, disable this at the project level with `create_firewall_rules: false`:
739
+
a rule that opens port 22 to `0.0.0.0/0`, disable this at the project level with `create_firewall_rules: false`:
738
740
739
741
```yaml
740
742
projects:
@@ -749,7 +751,9 @@ gcloud projects list --format="json(projectId)"
749
751
```
750
752
751
753
You're then responsible for ensuring your VPC's own firewall rules allow whatever SSH and cluster traffic
752
-
`dstack` needs.
754
+
`dstack` needs. This setting only affects the instance SSH rule — the separate firewall rule `dstack`
755
+
creates for gateways (allowing HTTP/HTTPS from the internet, scoped to the `dstack-gateway-instance`
756
+
target tag) is always auto-managed, since gateways are meant to be internet-reachable.
753
757
754
758
### Lambda
755
759
@@ -1158,8 +1162,13 @@ There are two ways to configure OCI: using client credentials or using the defau
1158
1162
```
1159
1163
1160
1164
??? info "Custom network security group"
1161
-
By default, `dstack` creates and manages its own network security group per project (opening SSH to
1162
-
`0.0.0.0/0`and allowing all traffic within the VCN so multi-node clusters work out of the box).
1165
+
By default, `dstack` places instances in a shared subnet whose OCI security list opens SSH
1166
+
(TCP port 22) to `0.0.0.0/0` and permits all outbound traffic. On top of that, `dstack` creates
1167
+
and manages its own network security group (NSG) per project, which only adds a rule allowing all
1168
+
traffic within the group so multi-node clusters work out of the box. In other words, the
1169
+
permissive SSH ingress and the outbound access come from the subnet's security list, not from the
1170
+
auto-managed NSG.
1171
+
1163
1172
OCI network security groups are region-scoped, so a custom NSG is configured per region via
1164
1173
`network_security_group_ids`:
1165
1174
@@ -1176,9 +1185,20 @@ There are two ways to configure OCI: using client credentials or using the defau
1176
1185
```
1177
1186
1178
1187
Regions not covered by `network_security_group_ids` fall back to dstack's auto-created network
1179
-
security group. Either way, `dstack` attaches the network security group to instances as-is and
1180
-
never adds, removes, or modifies its rules. You're responsible for SSH reachability and, for
1181
-
multi-node clusters, for allowing traffic between instances in the group.
1188
+
security group and shared subnet.
1189
+
1190
+
When a custom NSG is used, `dstack` never adds, removes, or modifies its rules, and it places the
1191
+
affected instances in a separate VCN and subnet that has **no** OCI security list (a second subnet
1192
+
in the same VCN isn't possible here, since the default subnet already occupies the whole VCN's
1193
+
address space). This makes the NSG the sole security boundary — there is no longer any implicit
1194
+
SSH-from-anywhere or implicit outbound-all coming from a security list. As a result, your custom
1195
+
NSG is fully responsible for:
1196
+
1197
+
- **Ingress**, including SSH (TCP port 22) from wherever you connect.
1198
+
- **Egress**, including outbound internet access. Without an egress rule (e.g. allow all to
1199
+
`0.0.0.0/0`), instances will have no outbound connectivity and will fail to pull Docker images
1200
+
and start runs.
1201
+
- For multi-node clusters, **traffic between instances** in the group.
1182
1202
1183
1203
You can also override this per fleet or run using the `security_group` profile property.
0 commit comments