upsert-slr 1.0.7__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.
upsert_slr/__init__.py ADDED
@@ -0,0 +1,190 @@
1
+ r'''
2
+ # Upsert Service-Linked Role
3
+
4
+ AWS CDK construct to create a [service-linked role (SLR)](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) if there is no SLR for the same service, and if there is, skip the creation process.
5
+
6
+ ![architecture](imgs/architecture.png)
7
+
8
+ ## Features
9
+
10
+ * Create a service-linked role. If it is already created in the same AWS account, just skip the creation.
11
+ * Standalone CFn template since no CDK assets are used. We use inline code for the Lambda function.
12
+ * Sleep some time after role creation to wait for IAM propagation.
13
+
14
+ ## Usage
15
+
16
+ ```sh
17
+ npm install upsert-slr
18
+ ```
19
+
20
+ ```python
21
+ import { ServiceLinkedRole } from 'upsert-slr';
22
+
23
+ new ServiceLinkedRole(this, 'ElasticsearchSlr', {
24
+ awsServiceName: 'es.amazonaws.com',
25
+ description: 'Service linked role for Elasticsearch',
26
+ });
27
+ ```
28
+
29
+ ## Why do we need this?
30
+
31
+ CloudFormation also supports a service-linked role ([doc](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servicelinkedrole.html)). Why do we need this?
32
+
33
+ Because the resource behaves strangely when there is already a role with the same name. All we need is to simply create a role, and skip it if it already exists. Such behavior as upsert is achieved by this construct, `upsert-slr`.
34
+
35
+ Also, even if CFn successfully creates a role, resources that depend on the role sometimes fail to be created because there is sometimes a delay before the role is actually available. See [this stack overflow](https://stackoverflow.com/questions/20156043/how-long-should-i-wait-after-applying-an-aws-iam-policy-before-it-is-valid) for more details.
36
+
37
+ To avoid the IAM propagation delay, this construct also waits for some time after a role is created.
38
+ '''
39
+ from pkgutil import extend_path
40
+ __path__ = extend_path(__path__, __name__)
41
+
42
+ import abc
43
+ import builtins
44
+ import datetime
45
+ import enum
46
+ import typing
47
+
48
+ import jsii
49
+ import publication
50
+ import typing_extensions
51
+
52
+ import typeguard
53
+ from importlib.metadata import version as _metadata_package_version
54
+ TYPEGUARD_MAJOR_VERSION = int(_metadata_package_version('typeguard').split('.')[0])
55
+
56
+ def check_type(argname: str, value: object, expected_type: typing.Any) -> typing.Any:
57
+ if TYPEGUARD_MAJOR_VERSION <= 2:
58
+ return typeguard.check_type(argname=argname, value=value, expected_type=expected_type) # type:ignore
59
+ else:
60
+ if isinstance(value, jsii._reference_map.InterfaceDynamicProxy): # pyright: ignore [reportAttributeAccessIssue]
61
+ pass
62
+ else:
63
+ if TYPEGUARD_MAJOR_VERSION == 3:
64
+ typeguard.config.collection_check_strategy = typeguard.CollectionCheckStrategy.ALL_ITEMS # type:ignore
65
+ typeguard.check_type(value=value, expected_type=expected_type) # type:ignore
66
+ else:
67
+ typeguard.check_type(value=value, expected_type=expected_type, collection_check_strategy=typeguard.CollectionCheckStrategy.ALL_ITEMS) # type:ignore
68
+
69
+ from ._jsii import *
70
+
71
+ import constructs as _constructs_77d1e7e8
72
+
73
+
74
+ class ServiceLinkedRole(
75
+ _constructs_77d1e7e8.Construct,
76
+ metaclass=jsii.JSIIMeta,
77
+ jsii_type="upsert-slr.ServiceLinkedRole",
78
+ ):
79
+ def __init__(
80
+ self,
81
+ scope: "_constructs_77d1e7e8.Construct",
82
+ id: builtins.str,
83
+ *,
84
+ aws_service_name: builtins.str,
85
+ description: typing.Optional[builtins.str] = None,
86
+ ) -> None:
87
+ '''
88
+ :param scope: -
89
+ :param id: -
90
+ :param aws_service_name: The service principal for the AWS service to which this role is attached. You use a string similar to a URL but without the http:// in front. For example: elasticbeanstalk.amazonaws.com . Service principals are unique and case-sensitive. To find the exact service principal for your service-linked role, see AWS services that work with IAM in the IAM User Guide. Look for the services that have Yes in the Service-Linked Role column. Choose the Yes link to view the service-linked role documentation for that service. https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html
91
+ :param description: The description of the role. This is only used when creating a new role. When there is an existing role for the aws service, this field is ignored. Default: no description
92
+ '''
93
+ if __debug__:
94
+ type_hints = typing.get_type_hints(_typecheckingstub__eaefcb6bfa6686267d9fbe8ed893ee66abd33592269a0f87588ddf3ea490fc74)
95
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
96
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
97
+ props = ServiceLinkedRoleProps(
98
+ aws_service_name=aws_service_name, description=description
99
+ )
100
+
101
+ jsii.create(self.__class__, self, [scope, id, props])
102
+
103
+
104
+ @jsii.data_type(
105
+ jsii_type="upsert-slr.ServiceLinkedRoleProps",
106
+ jsii_struct_bases=[],
107
+ name_mapping={"aws_service_name": "awsServiceName", "description": "description"},
108
+ )
109
+ class ServiceLinkedRoleProps:
110
+ def __init__(
111
+ self,
112
+ *,
113
+ aws_service_name: builtins.str,
114
+ description: typing.Optional[builtins.str] = None,
115
+ ) -> None:
116
+ '''
117
+ :param aws_service_name: The service principal for the AWS service to which this role is attached. You use a string similar to a URL but without the http:// in front. For example: elasticbeanstalk.amazonaws.com . Service principals are unique and case-sensitive. To find the exact service principal for your service-linked role, see AWS services that work with IAM in the IAM User Guide. Look for the services that have Yes in the Service-Linked Role column. Choose the Yes link to view the service-linked role documentation for that service. https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html
118
+ :param description: The description of the role. This is only used when creating a new role. When there is an existing role for the aws service, this field is ignored. Default: no description
119
+ '''
120
+ if __debug__:
121
+ type_hints = typing.get_type_hints(_typecheckingstub__2b465f6bb28878e03ea2345c60b3a08d2ec8243a9fd855266499358ddd9a2940)
122
+ check_type(argname="argument aws_service_name", value=aws_service_name, expected_type=type_hints["aws_service_name"])
123
+ check_type(argname="argument description", value=description, expected_type=type_hints["description"])
124
+ self._values: typing.Dict[builtins.str, typing.Any] = {
125
+ "aws_service_name": aws_service_name,
126
+ }
127
+ if description is not None:
128
+ self._values["description"] = description
129
+
130
+ @builtins.property
131
+ def aws_service_name(self) -> builtins.str:
132
+ '''The service principal for the AWS service to which this role is attached.
133
+
134
+ You use a string similar to a URL but without the http:// in front. For example: elasticbeanstalk.amazonaws.com .
135
+
136
+ Service principals are unique and case-sensitive. To find the exact service principal for your service-linked role, see AWS services that work with IAM in the IAM User Guide. Look for the services that have Yes in the Service-Linked Role column. Choose the Yes link to view the service-linked role documentation for that service.
137
+ https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html
138
+ '''
139
+ result = self._values.get("aws_service_name")
140
+ assert result is not None, "Required property 'aws_service_name' is missing"
141
+ return typing.cast(builtins.str, result)
142
+
143
+ @builtins.property
144
+ def description(self) -> typing.Optional[builtins.str]:
145
+ '''The description of the role.
146
+
147
+ This is only used when creating a new role.
148
+ When there is an existing role for the aws service, this field is ignored.
149
+
150
+ :default: no description
151
+ '''
152
+ result = self._values.get("description")
153
+ return typing.cast(typing.Optional[builtins.str], result)
154
+
155
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
156
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
157
+
158
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
159
+ return not (rhs == self)
160
+
161
+ def __repr__(self) -> str:
162
+ return "ServiceLinkedRoleProps(%s)" % ", ".join(
163
+ k + "=" + repr(v) for k, v in self._values.items()
164
+ )
165
+
166
+
167
+ __all__ = [
168
+ "ServiceLinkedRole",
169
+ "ServiceLinkedRoleProps",
170
+ ]
171
+
172
+ publication.publish()
173
+
174
+ def _typecheckingstub__eaefcb6bfa6686267d9fbe8ed893ee66abd33592269a0f87588ddf3ea490fc74(
175
+ scope: _constructs_77d1e7e8.Construct,
176
+ id: builtins.str,
177
+ *,
178
+ aws_service_name: builtins.str,
179
+ description: typing.Optional[builtins.str] = None,
180
+ ) -> None:
181
+ """Type checking stubs"""
182
+ pass
183
+
184
+ def _typecheckingstub__2b465f6bb28878e03ea2345c60b3a08d2ec8243a9fd855266499358ddd9a2940(
185
+ *,
186
+ aws_service_name: builtins.str,
187
+ description: typing.Optional[builtins.str] = None,
188
+ ) -> None:
189
+ """Type checking stubs"""
190
+ pass
@@ -0,0 +1,42 @@
1
+ from pkgutil import extend_path
2
+ __path__ = extend_path(__path__, __name__)
3
+
4
+ import abc
5
+ import builtins
6
+ import datetime
7
+ import enum
8
+ import typing
9
+
10
+ import jsii
11
+ import publication
12
+ import typing_extensions
13
+
14
+ import typeguard
15
+ from importlib.metadata import version as _metadata_package_version
16
+ TYPEGUARD_MAJOR_VERSION = int(_metadata_package_version('typeguard').split('.')[0])
17
+
18
+ def check_type(argname: str, value: object, expected_type: typing.Any) -> typing.Any:
19
+ if TYPEGUARD_MAJOR_VERSION <= 2:
20
+ return typeguard.check_type(argname=argname, value=value, expected_type=expected_type) # type:ignore
21
+ else:
22
+ if isinstance(value, jsii._reference_map.InterfaceDynamicProxy): # pyright: ignore [reportAttributeAccessIssue]
23
+ pass
24
+ else:
25
+ if TYPEGUARD_MAJOR_VERSION == 3:
26
+ typeguard.config.collection_check_strategy = typeguard.CollectionCheckStrategy.ALL_ITEMS # type:ignore
27
+ typeguard.check_type(value=value, expected_type=expected_type) # type:ignore
28
+ else:
29
+ typeguard.check_type(value=value, expected_type=expected_type, collection_check_strategy=typeguard.CollectionCheckStrategy.ALL_ITEMS) # type:ignore
30
+
31
+ import aws_cdk._jsii
32
+ import constructs._jsii
33
+
34
+ __jsii_assembly__ = jsii.JSIIAssembly.load(
35
+ "upsert-slr", "1.0.7", __name__[0:-6], "upsert-slr@1.0.7.jsii.tgz"
36
+ )
37
+
38
+ __all__ = [
39
+ "__jsii_assembly__",
40
+ ]
41
+
42
+ publication.publish()
upsert_slr/py.typed ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2026 tmokmss
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.1
2
+ Name: upsert-slr
3
+ Version: 1.0.7
4
+ Summary: Manage AWS service-linked roles in a better way.
5
+ Home-page: https://github.com/tmokmss/upsert-slr.git
6
+ Author: tmokmss<tmokmss@users.noreply.github.com>
7
+ License: MIT
8
+ Project-URL: Source, https://github.com/tmokmss/upsert-slr.git
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: JavaScript
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Typing :: Typed
17
+ Classifier: Development Status :: 5 - Production/Stable
18
+ Classifier: License :: OSI Approved
19
+ Requires-Python: ~=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: aws-cdk-lib <3.0.0,>=2.1.0
23
+ Requires-Dist: constructs <11.0.0,>=10.0.5
24
+ Requires-Dist: jsii <2.0.0,>=1.125.0
25
+ Requires-Dist: publication >=0.0.3
26
+ Requires-Dist: typeguard ==2.13.3
27
+
28
+ # Upsert Service-Linked Role
29
+
30
+ AWS CDK construct to create a [service-linked role (SLR)](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) if there is no SLR for the same service, and if there is, skip the creation process.
31
+
32
+ ![architecture](imgs/architecture.png)
33
+
34
+ ## Features
35
+
36
+ * Create a service-linked role. If it is already created in the same AWS account, just skip the creation.
37
+ * Standalone CFn template since no CDK assets are used. We use inline code for the Lambda function.
38
+ * Sleep some time after role creation to wait for IAM propagation.
39
+
40
+ ## Usage
41
+
42
+ ```sh
43
+ npm install upsert-slr
44
+ ```
45
+
46
+ ```python
47
+ import { ServiceLinkedRole } from 'upsert-slr';
48
+
49
+ new ServiceLinkedRole(this, 'ElasticsearchSlr', {
50
+ awsServiceName: 'es.amazonaws.com',
51
+ description: 'Service linked role for Elasticsearch',
52
+ });
53
+ ```
54
+
55
+ ## Why do we need this?
56
+
57
+ CloudFormation also supports a service-linked role ([doc](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servicelinkedrole.html)). Why do we need this?
58
+
59
+ Because the resource behaves strangely when there is already a role with the same name. All we need is to simply create a role, and skip it if it already exists. Such behavior as upsert is achieved by this construct, `upsert-slr`.
60
+
61
+ Also, even if CFn successfully creates a role, resources that depend on the role sometimes fail to be created because there is sometimes a delay before the role is actually available. See [this stack overflow](https://stackoverflow.com/questions/20156043/how-long-should-i-wait-after-applying-an-aws-iam-policy-before-it-is-valid) for more details.
62
+
63
+ To avoid the IAM propagation delay, this construct also waits for some time after a role is created.
@@ -0,0 +1,9 @@
1
+ upsert_slr/__init__.py,sha256=cJIDaMfELQAEf5ekmHpg3TQPa1dDU50G3JMhMS0fNjE,9011
2
+ upsert_slr/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
+ upsert_slr/_jsii/__init__.py,sha256=wNq2GUOUbT-5aNRzTgbeuJafvnxxH155IvkWsL3neFI,1431
4
+ upsert_slr/_jsii/upsert-slr@1.0.7.jsii.tgz,sha256=KPI5kTLxeAuTZ_pXR9w-kuNEn3_UzId6defV7SfBCJE,52812
5
+ upsert_slr-1.0.7.dist-info/LICENSE,sha256=1YYoNgeQ6B8y9vIty3QDDD_t48nYzUoHwiLOTI5a4W4,1051
6
+ upsert_slr-1.0.7.dist-info/METADATA,sha256=9wZuV0PoeZfmInwvoGvYC2lH9LSf8OzNLYrUzFNHiVs,2777
7
+ upsert_slr-1.0.7.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
8
+ upsert_slr-1.0.7.dist-info/top_level.txt,sha256=x0hhdmxmID546u8_HGfktN_5e8MB8JI0S7zRGjdolkQ,11
9
+ upsert_slr-1.0.7.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.3.3)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ upsert_slr