@@ -82,20 +82,34 @@ def create_security_group(
8282 create_security_group_kwargs = {}
8383 if vpc_id is not None :
8484 create_security_group_kwargs ["VpcId" ] = vpc_id
85- security_group = ec2_client .create_security_group (
86- Description = "Generated by dstack" ,
87- GroupName = security_group_name ,
88- TagSpecifications = [
89- {
90- "ResourceType" : "security-group" ,
91- "Tags" : [
92- {"Key" : "owner" , "Value" : "dstack" },
93- {"Key" : "dstack_project" , "Value" : project_id },
94- ],
95- },
96- ],
97- ** create_security_group_kwargs ,
98- )
85+ try :
86+ security_group = ec2_client .create_security_group (
87+ Description = "Generated by dstack" ,
88+ GroupName = security_group_name ,
89+ TagSpecifications = [
90+ {
91+ "ResourceType" : "security-group" ,
92+ "Tags" : [
93+ {"Key" : "owner" , "Value" : "dstack" },
94+ {"Key" : "dstack_project" , "Value" : project_id },
95+ ],
96+ },
97+ ],
98+ ** create_security_group_kwargs ,
99+ )
100+ except botocore .exceptions .ClientError as e :
101+ if e .response .get ("Error" , {}).get ("Code" ) != "InvalidGroup.Duplicate" :
102+ raise
103+ # The group was created concurrently, e.g. by another instance provisioning
104+ response = ec2_client .describe_security_groups (
105+ Filters = describe_security_groups_filters
106+ )
107+ if not response .get ("SecurityGroups" ):
108+ raise ComputeError (
109+ f"Security group { security_group_name } reported as duplicate"
110+ " but not found when describing it"
111+ ) from e
112+ security_group = response ["SecurityGroups" ][0 ]
99113 security_group_id = security_group ["GroupId" ]
100114
101115 _add_ingress_security_group_rule_if_missing (
@@ -486,10 +500,16 @@ def _add_ingress_security_group_rule_if_missing(
486500) -> bool :
487501 if _rule_exists (rule , security_group .get ("IpPermissions" , [])):
488502 return False
489- ec2_client .authorize_security_group_ingress (
490- GroupId = security_group_id ,
491- IpPermissions = [rule ],
492- )
503+ try :
504+ ec2_client .authorize_security_group_ingress (
505+ GroupId = security_group_id ,
506+ IpPermissions = [rule ],
507+ )
508+ except botocore .exceptions .ClientError as e :
509+ if e .response .get ("Error" , {}).get ("Code" ) == "InvalidPermission.Duplicate" :
510+ # The rule was added concurrently
511+ return False
512+ raise
493513 return True
494514
495515
@@ -501,10 +521,16 @@ def _add_egress_security_group_rule_if_missing(
501521) -> bool :
502522 if _rule_exists (rule , security_group .get ("IpPermissionsEgress" , [])):
503523 return False
504- ec2_client .authorize_security_group_egress (
505- GroupId = security_group_id ,
506- IpPermissions = [rule ],
507- )
524+ try :
525+ ec2_client .authorize_security_group_egress (
526+ GroupId = security_group_id ,
527+ IpPermissions = [rule ],
528+ )
529+ except botocore .exceptions .ClientError as e :
530+ if e .response .get ("Error" , {}).get ("Code" ) == "InvalidPermission.Duplicate" :
531+ # The rule was added concurrently
532+ return False
533+ raise
508534 return True
509535
510536
0 commit comments