simple_aws_ssm_parameter_store 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ # -*- coding: utf-8 -*-
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from .constants import ParameterType
4
+ from .constants import ParameterTier
5
+ from .constants import ResourceType
6
+ from .constants import DEFAULT_KMS_KEY
7
+ from .utils import encode_tags
8
+ from .utils import decode_tags
9
+ from .model import Parameter
10
+ from .client import get_parameter
11
+ from .client import put_parameter_if_changed
12
+ from .client import delete_parameter
13
+ from .client import get_parameter_tags
14
+ from .client import remove_parameter_tags
15
+ from .client import update_parameter_tags
16
+ from .client import put_parameter_tags
@@ -0,0 +1,590 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Enhanced boto3 SSM client functions.
5
+
6
+ This module provides high-level, Pythonic wrapper functions around the AWS SSM
7
+ Parameter Store boto3 client operations. The functions handle error cases gracefully,
8
+ provide better return values, and implement common patterns like existence testing
9
+ and idempotent operations.
10
+ """
11
+
12
+ import typing as T
13
+ import json
14
+
15
+ import botocore.exceptions
16
+ from func_args.api import OPT
17
+ from func_args.api import remove_optional
18
+
19
+ from .constants import ParameterType
20
+ from .constants import ParameterTier
21
+ from .constants import ResourceType
22
+ from .utils import encode_tags
23
+ from .utils import decode_tags
24
+ from .model import Parameter
25
+
26
+ if T.TYPE_CHECKING: # pragma: no cover
27
+ from mypy_boto3_ssm.client import SSMClient
28
+
29
+
30
+ def get_parameter(
31
+ ssm_client: "SSMClient",
32
+ name: str,
33
+ with_decryption: bool = False,
34
+ ) -> Parameter | None:
35
+ """
36
+ Get a parameter by name with built-in existence testing.
37
+
38
+ This function provides a convenient way to retrieve parameters while gracefully
39
+ handling non-existent parameters. Unlike the raw boto3 client which raises
40
+ exceptions for missing parameters, this function returns None, making it ideal
41
+ for existence testing and conditional parameter access.
42
+
43
+ Example usage for existence testing::
44
+
45
+ param = get_parameter(ssm_client, "/my/param")
46
+ if param is not None:
47
+ print("Parameter exists")
48
+ else:
49
+ print("Parameter does not exist")
50
+
51
+ Ref:
52
+
53
+ - `get_parameter <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter>`_
54
+
55
+ :param ssm_client: SSM client
56
+ :param name: parameter name (e.g., "/app/database/host")
57
+ :param with_decryption: whether to decrypt SecureString parameter values
58
+
59
+ :return: ``Parameter`` object if the parameter exists, None if it does not exist.
60
+ """
61
+ try:
62
+ response = ssm_client.get_parameter(
63
+ Name=name,
64
+ **remove_optional(
65
+ WithDecryption=with_decryption,
66
+ ),
67
+ )
68
+ return Parameter(_data=response["Parameter"])
69
+ except botocore.exceptions.ClientError as e:
70
+ if e.response["Error"]["Code"] in [
71
+ "ParameterNotFound",
72
+ "ParameterVersionNotFound",
73
+ ]:
74
+ return None
75
+ raise # pragma: no cover
76
+
77
+
78
+ def _get_parameter_metadata(
79
+ ssm_client: "SSMClient",
80
+ name: str,
81
+ ) -> dict[str, T.Any]:
82
+ """
83
+ Get the metadata of a parameter that ``get_parameter`` does not return,
84
+ such as ``Description``, ``Tier``, ``KeyId``, ``AllowedPattern``, and ``Policies``.
85
+
86
+ Ref:
87
+
88
+ - `describe_parameters <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.describe_parameters>`_
89
+
90
+ :param ssm_client: SSM client
91
+ :param name: parameter name (e.g., "/app/database/host")
92
+
93
+ :return: The ``describe_parameters`` item of the parameter, or an empty dict
94
+ if the parameter does not exist.
95
+ """
96
+ response = ssm_client.describe_parameters(
97
+ ParameterFilters=[
98
+ {
99
+ "Key": "Name",
100
+ "Option": "Equals",
101
+ "Values": [name],
102
+ },
103
+ ],
104
+ )
105
+ for item in response.get("Parameters", []):
106
+ if item["Name"] == name:
107
+ return item
108
+ return {}
109
+
110
+
111
+ def _is_same_policies(
112
+ desired: str,
113
+ current: list[dict[str, str]] | None,
114
+ ) -> bool:
115
+ """
116
+ Compare the ``Policies`` JSON string passed to ``put_parameter`` with the
117
+ ``Policies`` list returned by ``describe_parameters``, ignoring key order
118
+ and policy order.
119
+
120
+ :param desired: the JSON array string to pass to ``put_parameter``
121
+ :param current: the ``Policies`` list of a ``describe_parameters`` item
122
+
123
+ :return: True only if both hold the same policies. Anything that cannot be
124
+ parsed counts as different, so the caller writes rather than skips.
125
+ """
126
+ try:
127
+ desired_policies = json.loads(desired)
128
+ if isinstance(desired_policies, dict):
129
+ desired_policies = [desired_policies]
130
+ current_policies = []
131
+ for policy in current or []:
132
+ current_policies.append(json.loads(policy["PolicyText"]))
133
+ desired_keys = sorted(json.dumps(p, sort_keys=True) for p in desired_policies)
134
+ current_keys = sorted(json.dumps(p, sort_keys=True) for p in current_policies)
135
+ except (ValueError, KeyError, TypeError):
136
+ return False
137
+ return desired_keys == current_keys
138
+
139
+
140
+ def _is_parameter_changed(
141
+ ssm_client: "SSMClient",
142
+ before_param: Parameter,
143
+ value: str,
144
+ description: str | None = OPT,
145
+ type: str | None = OPT,
146
+ tier: str | None = OPT,
147
+ key_id: str | None = OPT,
148
+ allowed_pattern: str | None = OPT,
149
+ policies: str | None = OPT,
150
+ data_type: str | None = OPT,
151
+ ) -> bool:
152
+ """
153
+ Check whether an existing parameter differs from the desired state.
154
+
155
+ Only the arguments that are passed are compared; an argument left as ``OPT``
156
+ means "keep whatever is there". ``describe_parameters`` is called only when
157
+ one of the fields it alone returns is passed.
158
+
159
+ :param before_param: the current parameter, read with decryption
160
+ :param type: the parameter type as a plain string (e.g. "SecureString")
161
+ :param tier: the parameter tier as a plain string (e.g. "Standard")
162
+
163
+ :return: True if ``put_parameter`` has to be called.
164
+ """
165
+ if value != before_param.value:
166
+ return True
167
+ if type is not OPT and type != before_param.type:
168
+ return True
169
+ if data_type is not OPT and data_type != before_param.data_type:
170
+ return True
171
+
172
+ # These fields are only returned by describe_parameters
173
+ metadata_args = [description, tier, key_id, allowed_pattern, policies]
174
+ if all(arg is OPT for arg in metadata_args):
175
+ return False
176
+ metadata = _get_parameter_metadata(ssm_client, before_param.name)
177
+ if description is not OPT and description != metadata.get("Description", ""):
178
+ return True
179
+ # An Intelligent-Tiering parameter is stored as Standard or Advanced,
180
+ # so there is nothing to compare it with
181
+ if tier is not OPT and tier != ParameterTier.INTELLIGENT_TIERING.value:
182
+ if tier != metadata.get("Tier"):
183
+ return True
184
+ if key_id is not OPT and key_id != metadata.get("KeyId"):
185
+ return True
186
+ if allowed_pattern is not OPT:
187
+ if allowed_pattern != metadata.get("AllowedPattern", ""):
188
+ return True
189
+ if policies is not OPT:
190
+ if not _is_same_policies(policies, metadata.get("Policies")):
191
+ return True
192
+ return False
193
+
194
+
195
+ def _put_parameter_if_changed(
196
+ ssm_client: "SSMClient",
197
+ name: str,
198
+ value: str,
199
+ description: str | None = OPT,
200
+ type: str | None = OPT,
201
+ tier: str | None = OPT,
202
+ key_id: str | None = OPT,
203
+ allowed_pattern: str | None = OPT,
204
+ tags: dict[str, str] | None = OPT,
205
+ policies: str | None = OPT,
206
+ data_type: str | None = OPT,
207
+ ) -> tuple[Parameter | None, Parameter | None]:
208
+ """
209
+ One read-compare-write round of :func:`put_parameter_if_changed`, with
210
+ ``type`` and ``tier`` already converted to plain strings.
211
+
212
+ It raises the ``ParameterAlreadyExists`` error when another writer creates
213
+ the parameter between the read and the write.
214
+ """
215
+ # Always decrypt: the flag is ignored for String and StringList, and a
216
+ # SecureString can only be compared by its plain value
217
+ before_param = get_parameter(ssm_client, name, with_decryption=True)
218
+ is_param_exists = before_param is not None
219
+
220
+ if is_param_exists:
221
+ should_write = _is_parameter_changed(
222
+ ssm_client=ssm_client,
223
+ before_param=before_param,
224
+ value=value,
225
+ description=description,
226
+ type=type,
227
+ tier=tier,
228
+ key_id=key_id,
229
+ allowed_pattern=allowed_pattern,
230
+ policies=policies,
231
+ data_type=data_type,
232
+ )
233
+ else:
234
+ should_write = True
235
+
236
+ if should_write is False:
237
+ return before_param, None
238
+
239
+ kwargs = dict(
240
+ Name=name,
241
+ Value=value,
242
+ Description=description,
243
+ Type=type,
244
+ Tier=tier,
245
+ KeyId=key_id,
246
+ AllowedPattern=allowed_pattern,
247
+ Policies=policies,
248
+ DataType=data_type,
249
+ )
250
+ if is_param_exists:
251
+ # put_parameter does not accept Tags together with Overwrite;
252
+ # the caller syncs the tags of an existing parameter separately
253
+ kwargs["Overwrite"] = True
254
+ elif isinstance(tags, dict) and len(tags):
255
+ kwargs["Tags"] = encode_tags(tags)
256
+ # Without Overwrite, this fails with ParameterAlreadyExists instead of
257
+ # replacing a parameter that another writer has just created
258
+ response = ssm_client.put_parameter(**remove_optional(**kwargs))
259
+
260
+ # put_parameter only returns Version and Tier, so build the rest from the input
261
+ if type is OPT and is_param_exists:
262
+ type = before_param.type
263
+ param_data = dict(
264
+ Name=name,
265
+ Value=value,
266
+ Description=description,
267
+ Type=type,
268
+ Tier=tier,
269
+ )
270
+ param_data = remove_optional(**param_data)
271
+ param_data.update(response)
272
+ after_param = Parameter(_data=param_data)
273
+ return before_param, after_param
274
+
275
+
276
+ def put_parameter_if_changed(
277
+ ssm_client: "SSMClient",
278
+ name: str,
279
+ value: str,
280
+ description: str | None = OPT,
281
+ type: ParameterType | None = OPT,
282
+ tier: ParameterTier | None = OPT,
283
+ key_id: str | None = OPT,
284
+ allowed_pattern: str | None = OPT,
285
+ tags: dict[str, str] | None = OPT,
286
+ policies: str | None = OPT,
287
+ data_type: str | None = OPT,
288
+ ) -> tuple[Parameter | None, Parameter | None]:
289
+ """
290
+ Make a parameter match the desired state, writing a new version only when
291
+ something actually changed (conditional write).
292
+
293
+ The function reads the parameter, compares it with the arguments you pass,
294
+ and calls ``put_parameter`` only if the parameter does not exist or differs.
295
+ Running it again with the same arguments writes nothing.
296
+
297
+ **Why This Matters - Version History Preservation:**
298
+
299
+ AWS SSM Parameter Store only retains the last 100 parameter versions. During
300
+ development, debugging, or frequent deployments, blindly calling put_parameter()
301
+ can rapidly consume this version history - even when values haven't actually
302
+ changed. This can make older parameter versions permanently inaccessible.
303
+
304
+ **What is compared:**
305
+
306
+ - ``value``, always. The current value is read with decryption, so a
307
+ ``SecureString`` is compared by its plain value whether or not you pass
308
+ ``type``. This needs ``kms:Decrypt`` on its KMS key.
309
+ - ``description``, ``type``, ``tier``, ``key_id``, ``allowed_pattern``,
310
+ ``policies``, and ``data_type``, but only the ones you pass. An argument you
311
+ leave out keeps whatever the parameter has. ``tier=INTELLIGENT_TIERING``
312
+ is not compared, because AWS stores such a parameter as Standard or Advanced.
313
+
314
+ **Tags:**
315
+
316
+ When you pass ``tags``, they become the parameter's full tag set: on create
317
+ they are sent with ``put_parameter``; on an existing parameter they are
318
+ replaced with :func:`put_parameter_tags`, only if they differ. Tag changes
319
+ do not create a parameter version. Leave ``tags`` out to keep the tags as they are.
320
+
321
+ **Concurrency:**
322
+
323
+ The read and the write are separate calls, and SSM has no conditional write,
324
+ so this is a best effort. If another writer creates the parameter between
325
+ the read and the write, the create fails with ``ParameterAlreadyExists``;
326
+ the function then reads and compares once more. Two writers that update an
327
+ existing parameter at the same time can still both write: serialize such
328
+ writers outside this library.
329
+
330
+ Example usage::
331
+
332
+ # Create or update parameter only if value changed
333
+ before, after = put_parameter_if_changed(
334
+ ssm_client=client,
335
+ name="/app/database/host",
336
+ value="new-db-host.example.com",
337
+ type=ParameterType.STRING
338
+ )
339
+
340
+ if after is not None:
341
+ print(f"Parameter updated: version {after.version}")
342
+ else:
343
+ print("No update needed - value unchanged")
344
+
345
+ Return value interpretation:
346
+
347
+ - ``(None, Parameter)``: Parameter didn't exist, was created
348
+ - ``(Parameter, None)``: Parameter already matched, nothing was written
349
+ - ``(Parameter, Parameter)``: Parameter differed, a new version was written
350
+
351
+ Ref:
352
+
353
+ - `put_parameter <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.put_parameter>`_
354
+
355
+ :param ssm_client: SSM client
356
+ :param name: parameter name (e.g., "/app/database/host")
357
+ :param value: parameter value to set
358
+ :param description: parameter description
359
+ :param type: parameter type (String, StringList, SecureString)
360
+ :param tier: parameter tier (Standard, Advanced, Intelligent-Tiering)
361
+ :param key_id: KMS key ID for SecureString encryption
362
+ :param allowed_pattern: regex pattern for parameter validation
363
+ :param tags: the full tag set of the parameter, as key-value pairs
364
+ :param policies: parameter policies (JSON string)
365
+ :param data_type: parameter data type (e.g., "text", "aws:ec2:image")
366
+
367
+ :returns: Tuple of (before_parameter, after_parameter) where:
368
+ - before_parameter: Parameter object before operation (None if didn't exist)
369
+ - after_parameter: Parameter object after operation (None if no write occurred)
370
+ """
371
+ kwargs = dict(
372
+ ssm_client=ssm_client,
373
+ name=name,
374
+ value=value,
375
+ description=description,
376
+ type=type.value if isinstance(type, ParameterType) else type,
377
+ tier=tier.value if isinstance(tier, ParameterTier) else tier,
378
+ key_id=key_id,
379
+ allowed_pattern=allowed_pattern,
380
+ tags=tags,
381
+ policies=policies,
382
+ data_type=data_type,
383
+ )
384
+ try:
385
+ before_param, after_param = _put_parameter_if_changed(**kwargs)
386
+ except botocore.exceptions.ClientError as e:
387
+ if e.response["Error"]["Code"] != "ParameterAlreadyExists":
388
+ raise # pragma: no cover
389
+ # Another writer created it between our read and write: compare again
390
+ before_param, after_param = _put_parameter_if_changed(**kwargs)
391
+
392
+ if isinstance(tags, dict) and before_param is not None:
393
+ if get_parameter_tags(ssm_client, name) != tags:
394
+ put_parameter_tags(ssm_client, name, tags)
395
+
396
+ return before_param, after_param
397
+
398
+
399
+ def delete_parameter(
400
+ ssm_client: "SSMClient",
401
+ name: str,
402
+ ) -> bool:
403
+ """
404
+ Delete a parameter by name with idempotent behavior.
405
+
406
+ This function provides idempotent parameter deletion - it can be called multiple
407
+ times safely without raising errors. Unlike the raw boto3 client which raises
408
+ ParameterNotFound exceptions, this function returns False for non-existent
409
+ parameters, making it safe to use in cleanup operations and automation scripts.
410
+
411
+ The idempotent behavior ensures that:
412
+
413
+ - If the parameter exists, it will be deleted and return True
414
+ - If the parameter doesn't exist, it returns False without raising an error
415
+ - Multiple calls with the same parameter name are safe
416
+
417
+ Example usage in cleanup scripts::
418
+
419
+ # Safe to call even if parameter doesn't exist
420
+ deleted = delete_parameter(client, "/app/temp/config")
421
+ if deleted:
422
+ print("Parameter was deleted")
423
+ else:
424
+ print("Parameter did not exist")
425
+
426
+ Ref:
427
+
428
+ - `delete_parameter <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.delete_parameter>`_
429
+
430
+ :param ssm_client: SSM client
431
+ :param name: parameter name (e.g., "/app/database/host")
432
+
433
+ :return: True if the parameter was deleted, False if it did not exist.
434
+ """
435
+ try:
436
+ ssm_client.delete_parameter(Name=name)
437
+ return True
438
+ except botocore.exceptions.ClientError as e:
439
+ if e.response["Error"]["Code"] == "ParameterNotFound":
440
+ return False
441
+ raise # pragma: no cover
442
+
443
+
444
+ def get_parameter_tags(
445
+ ssm_client: "SSMClient",
446
+ name: str,
447
+ ) -> dict[str, str]:
448
+ """
449
+ Get all tags associated with a parameter.
450
+
451
+ This function retrieves all tags for the specified parameter and returns them
452
+ as a convenient key-value dictionary. If the parameter has no tags, an empty
453
+ dictionary is returned.
454
+
455
+ Ref:
456
+
457
+ - `list_tags_for_resource <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.list_tags_for_resource>`_
458
+
459
+ :param ssm_client: SSM client
460
+ :param name: parameter name (e.g., "/app/database/host")
461
+
462
+ :return: Dictionary of tag key-value pairs. Empty dict if parameter has no tags.
463
+ """
464
+ response = ssm_client.list_tags_for_resource(
465
+ ResourceType=ResourceType.PARAMETER.value,
466
+ ResourceId=name,
467
+ )
468
+ return decode_tags(response.get("TagList", []))
469
+
470
+
471
+ def remove_parameter_tags(
472
+ ssm_client: "SSMClient",
473
+ name: str,
474
+ tag_keys: list[str],
475
+ ):
476
+ """
477
+ Remove specific tags from a parameter by tag keys.
478
+
479
+ This function removes only the specified tag keys from the parameter, leaving
480
+ other tags unchanged. It's useful for selective tag cleanup without affecting
481
+ the entire tag set.
482
+
483
+ Example::
484
+
485
+ # Remove only the "Environment" and "Team" tags
486
+ remove_parameter_tags(client, "/app/config", ["Environment", "Team"])
487
+
488
+ Ref:
489
+
490
+ - `remove_tags_from_resource <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.remove_tags_from_resource>`_
491
+
492
+ :param ssm_client: SSM client
493
+ :param name: parameter name (e.g., "/app/database/host")
494
+ :param tag_keys: list of tag keys to remove (e.g., ["Environment", "Team"])
495
+ """
496
+ return ssm_client.remove_tags_from_resource(
497
+ ResourceType=ResourceType.PARAMETER.value,
498
+ ResourceId=name,
499
+ TagKeys=tag_keys,
500
+ )
501
+
502
+
503
+ def update_parameter_tags(
504
+ ssm_client: "SSMClient",
505
+ name: str,
506
+ tags: dict[str, str],
507
+ ):
508
+ """
509
+ Add or update specific tags on a parameter (partial update).
510
+
511
+ This function performs a partial update of parameter tags. It adds new tags
512
+ and updates existing tags with the provided key-value pairs, while leaving
513
+ other existing tags unchanged. This is useful for adding metadata without
514
+ affecting the entire tag set.
515
+
516
+ Example::
517
+
518
+ # Add/update only specific tags, keeping others intact
519
+ update_parameter_tags(client, "/app/config", {
520
+ "Environment": "production",
521
+ "LastUpdated": "2024-01-15"
522
+ })
523
+
524
+ Ref:
525
+
526
+ - `add_tags_to_resource <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.add_tags_to_resource>`_
527
+
528
+ :param ssm_client: SSM client
529
+ :param name: parameter name (e.g., "/app/database/host")
530
+ :param tags: dictionary of tag key-value pairs to add/update
531
+ """
532
+ return ssm_client.add_tags_to_resource(
533
+ ResourceType=ResourceType.PARAMETER.value,
534
+ ResourceId=name,
535
+ Tags=encode_tags(tags),
536
+ )
537
+
538
+
539
+ def put_parameter_tags(
540
+ ssm_client: "SSMClient",
541
+ name: str,
542
+ tags: dict[str, str],
543
+ ):
544
+ """
545
+ Replace all parameter tags with the provided tag set (full replacement).
546
+
547
+ This function performs a complete replacement of all parameter tags. It removes
548
+ all existing tags and replaces them with the provided tags. If an empty
549
+ dictionary is provided, all tags are removed from the parameter.
550
+
551
+ Behavior:
552
+
553
+ - Empty dict: Remove all existing tags from the parameter
554
+ - Non-empty dict: Replace all existing tags with the provided tags
555
+
556
+ Example::
557
+
558
+ # Replace all tags with new set
559
+ put_parameter_tags(client, "/app/config", {
560
+ "Environment": "production",
561
+ "Owner": "platform-team"
562
+ })
563
+
564
+ # Remove all tags
565
+ put_parameter_tags(client, "/app/config", {})
566
+
567
+ Ref:
568
+
569
+ - `add_tags_to_resource <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.add_tags_to_resource>`_
570
+
571
+ :param ssm_client: SSM client
572
+ :param name: parameter name (e.g., "/app/database/host")
573
+ :param tags: dictionary of tag key-value pairs to set (empty dict removes all tags)
574
+ """
575
+ existing_tags = get_parameter_tags(ssm_client, name)
576
+
577
+ if len(tags) == 0:
578
+ if len(existing_tags): # only run remove tags when there are existing tags
579
+ remove_parameter_tags(ssm_client, name, list(existing_tags))
580
+ else:
581
+ # if to-update tags is super set of the existing tags
582
+ # then no need to run remove tags
583
+ # otherwise, need to run remove tags
584
+ if not (len(set(existing_tags).difference(set(tags))) == 0):
585
+ remove_parameter_tags(ssm_client, name, list(existing_tags))
586
+ ssm_client.add_tags_to_resource(
587
+ ResourceType=ResourceType.PARAMETER.value,
588
+ ResourceId=name,
589
+ Tags=encode_tags(tags),
590
+ )
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import enum
4
+
5
+
6
+ class ParameterType(str, enum.Enum):
7
+ """
8
+ See `What is a parameter? <https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html#what-is-a-parameter>`_
9
+ """
10
+
11
+ STRING = "String"
12
+ STRING_LIST = "StringList"
13
+ SECURE_STRING = "SecureString"
14
+
15
+
16
+ class ParameterTier(str, enum.Enum):
17
+ """
18
+ See `Parameter tiers <https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-advanced-parameters.html>`_
19
+ """
20
+
21
+ STANDARD = "Standard"
22
+ ADVANCED = "Advanced"
23
+ INTELLIGENT_TIERING = "Intelligent-Tiering"
24
+
25
+
26
+ class ResourceType(str, enum.Enum):
27
+ """
28
+ Resource type parameter value enum for:
29
+
30
+ - `list_tags_for_resource <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.list_tags_for_resource>`_
31
+ """
32
+
33
+ DOCUMENT = "Document"
34
+ MANAGED_INSTANCE = "ManagedInstance"
35
+ MAINTENANCE_WINDOW = "MaintenanceWindow"
36
+ PARAMETER = "Parameter"
37
+ PATCH_BASELINE = "PatchBaseline"
38
+ OPS_ITEM = "OpsItem"
39
+ OPS_METADATA = "OpsMetadata"
40
+ AUTOMATION = "Automation"
41
+ ASSOCIATION = "Association"
42
+
43
+
44
+ DEFAULT_KMS_KEY = "alias/aws/ssm"