Skip to content

Commit fb42a08

Browse files
authored
CFNv2: Support stack sets (#12909)
1 parent 7ebcdac commit fb42a08

File tree

7 files changed

+360
-4
lines changed

7 files changed

+360
-4
lines changed

localstack-core/localstack/services/cloudformation/provider.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
ARN_STACK_REGEX = re.compile(
138138
r"arn:(aws|aws-us-gov|aws-cn):cloudformation:[-a-zA-Z0-9]+:\d{12}:stack/[a-zA-Z][-a-zA-Z0-9]*/[-a-zA-Z0-9:/._+]+"
139139
)
140+
ARN_STACK_SET_REGEX = re.compile(
141+
r"arn:(aws|aws-us-gov|aws-cn):cloudformation:[-a-zA-Z0-9]+:\d{12}:stack-set/[a-zA-Z][-a-zA-Z0-9]*/[-a-zA-Z0-9:/._+]+"
142+
)
140143

141144

142145
def clone_stack_params(stack_params):

localstack-core/localstack/services/cloudformation/stores.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from localstack.services.cloudformation.engine.entities import Stack, StackChangeSet, StackSet
66
from localstack.services.cloudformation.v2.entities import ChangeSet as ChangeSetV2
77
from localstack.services.cloudformation.v2.entities import Stack as StackV2
8+
from localstack.services.cloudformation.v2.entities import StackSet as StackSetV2
89
from localstack.services.stores import AccountRegionBundle, BaseStore, LocalAttribute
910

1011
LOG = logging.getLogger(__name__)
@@ -19,6 +20,7 @@ class CloudFormationStore(BaseStore):
1920

2021
# maps stack set ID to stack set details
2122
stack_sets: dict[str, StackSet] = LocalAttribute(default=dict)
23+
stack_sets_v2: dict[str, StackSetV2] = LocalAttribute(default=dict)
2224

2325
# maps macro ID to macros
2426
macros: dict[str, dict] = LocalAttribute(default=dict)

localstack-core/localstack/services/cloudformation/v2/entities.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@
88
ChangeSetType,
99
CreateChangeSetInput,
1010
CreateStackInput,
11+
CreateStackSetInput,
1112
ExecutionStatus,
1213
Output,
1314
Parameter,
1415
ResourceStatus,
1516
StackDriftInformation,
1617
StackDriftStatus,
1718
StackEvent,
19+
StackInstanceComprehensiveStatus,
20+
StackInstanceDetailedStatus,
21+
StackInstanceStatus,
1822
StackResource,
23+
StackSetOperation,
1924
StackStatus,
2025
StackStatusReason,
2126
)
@@ -270,3 +275,36 @@ def account_id(self) -> str:
270275
@property
271276
def region_name(self) -> str:
272277
return self.stack.region_name
278+
279+
280+
class StackInstance:
281+
def __init__(
282+
self, account_id: str, region_name: str, stack_set_id: str, operation_id: str, stack_id: str
283+
):
284+
self.account_id = account_id
285+
self.region_name = region_name
286+
self.stack_set_id = stack_set_id
287+
self.operation_id = operation_id
288+
self.stack_id = stack_id
289+
290+
self.status: StackInstanceStatus = StackInstanceStatus.CURRENT
291+
self.stack_instance_status = StackInstanceComprehensiveStatus(
292+
DetailedStatus=StackInstanceDetailedStatus.SUCCEEDED
293+
)
294+
295+
296+
class StackSet:
297+
stack_instances: list[StackInstance]
298+
operations: dict[str, StackSetOperation]
299+
300+
def __init__(self, account_id: str, region_name: str, request_payload: CreateStackSetInput):
301+
self.account_id = account_id
302+
self.region_name = region_name
303+
304+
self.stack_set_name = request_payload["StackSetName"]
305+
self.stack_set_id = f"{self.stack_set_name}:{long_uid()}"
306+
self.template_body = request_payload.get("TemplateBody")
307+
self.template_url = request_payload.get("TemplateURL")
308+
309+
self.stack_instances = []
310+
self.operations = {}

0 commit comments

Comments
 (0)