qontract-reconcile 0.10.2.dev299__py3-none-any.whl → 0.10.2.dev314__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.
@@ -1,4 +1,6 @@
1
1
  # ruff: noqa: N801
2
+ from __future__ import annotations
3
+
2
4
  import base64
3
5
  import enum
4
6
  import json
@@ -9,7 +11,6 @@ import re
9
11
  import string
10
12
  import tempfile
11
13
  from collections import Counter
12
- from collections.abc import Iterable, Mapping, MutableMapping
13
14
  from dataclasses import dataclass, field
14
15
  from ipaddress import (
15
16
  ip_address,
@@ -18,7 +19,10 @@ from ipaddress import (
18
19
  from json import JSONDecodeError
19
20
  from threading import Lock
20
21
  from typing import (
22
+ TYPE_CHECKING,
21
23
  Any,
24
+ Self,
25
+ TypeAlias,
22
26
  cast,
23
27
  )
24
28
 
@@ -34,12 +38,14 @@ from terrascript import (
34
38
  Backend,
35
39
  Block,
36
40
  Data,
41
+ Locals,
37
42
  Module,
38
43
  Output,
39
44
  Provider,
40
45
  Resource,
41
46
  Terraform,
42
47
  Terrascript,
48
+ Variable,
43
49
  data,
44
50
  provider,
45
51
  )
@@ -143,9 +149,6 @@ import reconcile.utils.aws_helper as awsh
143
149
  from reconcile import queries
144
150
  from reconcile.cli import TERRAFORM_VERSION
145
151
  from reconcile.github_org import get_default_config
146
- from reconcile.gql_definitions.fragments.aws_vpc_request import (
147
- VPCRequest,
148
- )
149
152
  from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
150
153
  NamespaceTerraformResourceLifecycleV1,
151
154
  )
@@ -168,10 +171,6 @@ from reconcile.utils.exceptions import (
168
171
  FetchResourceError,
169
172
  PrintToFileInGitRepositoryError,
170
173
  )
171
- from reconcile.utils.external_resource_spec import (
172
- ExternalResourceSpec,
173
- ExternalResourceSpecInventory,
174
- )
175
174
  from reconcile.utils.external_resources import (
176
175
  PROVIDER_AWS,
177
176
  get_external_resource_specs,
@@ -180,7 +179,6 @@ from reconcile.utils.git import is_file_in_git_repo
180
179
  from reconcile.utils.gitlab_api import GitLabApi
181
180
  from reconcile.utils.jenkins_api import JenkinsApi
182
181
  from reconcile.utils.jinja2.utils import process_extracurlyjinja2_template
183
- from reconcile.utils.ocm import OCMMap
184
182
  from reconcile.utils.password_validator import (
185
183
  PasswordPolicy,
186
184
  PasswordValidator,
@@ -189,6 +187,25 @@ from reconcile.utils.secret_reader import SecretReader, SecretReaderBase
189
187
  from reconcile.utils.terraform import safe_resource_id
190
188
  from reconcile.utils.vcs import VCS
191
189
 
190
+ if TYPE_CHECKING:
191
+ from collections.abc import Iterable, Mapping, MutableMapping
192
+
193
+ from reconcile.gql_definitions.fragments.aws_vpc_request import (
194
+ VPCRequest,
195
+ )
196
+ from reconcile.terraform_tgw_attachments import DesiredStateItem
197
+ from reconcile.terraform_users import Role
198
+ from reconcile.utils.external_resource_spec import (
199
+ ExternalResourceSpec,
200
+ ExternalResourceSpecInventory,
201
+ )
202
+ from reconcile.utils.ocm import OCMMap
203
+
204
+
205
+ TFResource: TypeAlias = type[
206
+ Resource | Data | Module | Provider | Variable | Output | Locals | Terraform
207
+ ]
208
+
192
209
  GH_BASE_URL = os.environ.get("GITHUB_API", "https://api.github.com")
193
210
  ROSA_AUTH_LOGTOES_RELEASE = "repos/app-sre/logs-to-elasticsearch-lambda/releases/latest"
194
211
  ROSA_AUTH_KINESIS_TO_OS_RELEASE = (
@@ -304,9 +321,12 @@ AWS_US_GOV_ELB_ACCOUNT_IDS = {
304
321
  "us-gov-east-1": "190560391635",
305
322
  }
306
323
 
324
+ VPC_REQUEST_DEFAULT_PRIVATE_SUBNET_TAGS = {"kubernetes.io/role/internal-elb": "1"}
325
+ VPC_REQUEST_DEFAULT_PUBLIC_SUBNET_TAGS = {"kubernetes.io/role/elb": "1"}
326
+
307
327
 
308
328
  class OutputResourceNameNotUniqueError(Exception):
309
- def __init__(self, namespace, duplicates):
329
+ def __init__(self, namespace: str | None, duplicates: Iterable[str]) -> None:
310
330
  self.namespace, self.duplicates = namespace, duplicates
311
331
  super().__init__(
312
332
  str.format(
@@ -326,7 +346,7 @@ class StateInaccessibleError(Exception):
326
346
 
327
347
 
328
348
  class UnknownProviderError(Exception):
329
- def __init__(self, msg):
349
+ def __init__(self, msg: str) -> None:
330
350
  super().__init__("unknown provider error: " + str(msg))
331
351
 
332
352
 
@@ -453,9 +473,9 @@ class TerrascriptClient:
453
473
  integration: str,
454
474
  integration_prefix: str,
455
475
  thread_pool_size: int,
456
- accounts: Iterable[dict[str, Any]],
476
+ accounts: Iterable[MutableMapping[str, Any]],
457
477
  settings: Mapping[str, Any] | None = None,
458
- prefetch_resources_by_schemas: list[str] | None = None,
478
+ prefetch_resources_by_schemas: Iterable[str] | None = None,
459
479
  secret_reader: SecretReaderBase | None = None,
460
480
  ) -> None:
461
481
  self.integration = integration
@@ -541,10 +561,10 @@ class TerrascriptClient:
541
561
  self.accounts = {a["name"]: a for a in filtered_accounts}
542
562
  self.uids = {a["name"]: a["uid"] for a in filtered_accounts}
543
563
  # default_regions info is needed in populate_tf_resource_rds, even in disabled accounts
544
- self.default_regions = {
564
+ self.default_regions: dict[str, str] = {
545
565
  a["name"]: a["resourcesDefaultRegion"] for a in accounts
546
566
  }
547
- self.partitions = {
567
+ self.partitions: dict[str, str] = {
548
568
  a["name"]: a.get("partition") or "aws" for a in filtered_accounts
549
569
  }
550
570
  self.rosa_auth_logtoes_zip = ""
@@ -566,19 +586,19 @@ class TerrascriptClient:
566
586
  for schema in prefetch_resources_by_schemas:
567
587
  self._resource_cache.update(self.prefetch_resources(schema))
568
588
 
569
- def __enter__(self):
589
+ def __enter__(self) -> Self:
570
590
  return self
571
591
 
572
- def __exit__(self, *exc):
592
+ def __exit__(self, *exc: Any) -> None:
573
593
  self.cleanup()
574
594
 
575
- def cleanup(self):
595
+ def cleanup(self) -> None:
576
596
  if self.gitlab is not None:
577
597
  self.gitlab.cleanup()
578
598
 
579
599
  @staticmethod
580
600
  def state_bucket_for_account(
581
- integration: str, account_name: str, config: dict[str, Any]
601
+ integration: str, account_name: str, config: Mapping[str, Any]
582
602
  ) -> Backend:
583
603
  # creds
584
604
  access_key_backend_value = config["aws_access_key_id"]
@@ -643,7 +663,7 @@ class TerrascriptClient:
643
663
  f.write(r.content)
644
664
  return zip_file
645
665
 
646
- def get_logtoes_zip(self, release_url):
666
+ def get_logtoes_zip(self, release_url: str) -> str:
647
667
  if not self.rosa_auth_logtoes_zip:
648
668
  with self.rosa_auth_logtoes_zip_lock:
649
669
  # this may have already happened, so we check again
@@ -656,7 +676,7 @@ class TerrascriptClient:
656
676
  return self.rosa_auth_logtoes_zip
657
677
  return self.download_logtoes_zip(release_url)
658
678
 
659
- def download_logtoes_zip(self, release_url):
679
+ def download_logtoes_zip(self, release_url: str) -> str:
660
680
  headers = {"Authorization": "token " + self.token}
661
681
  r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
662
682
  r.raise_for_status()
@@ -670,7 +690,7 @@ class TerrascriptClient:
670
690
  f.write(r.content)
671
691
  return zip_file
672
692
 
673
- def get_rosa_auth_pre_signup_zip(self, release_url):
693
+ def get_rosa_auth_pre_signup_zip(self, release_url: str) -> str:
674
694
  if not self.rosa_auth_pre_signup_zip:
675
695
  with self.rosa_auth_pre_signup_zip_lock:
676
696
  # this may have already happened, so we check again
@@ -685,7 +705,7 @@ class TerrascriptClient:
685
705
  return self.rosa_auth_pre_signup_zip
686
706
  return self.download_rosa_auth_pre_signup_zip(release_url)
687
707
 
688
- def download_rosa_auth_pre_signup_zip(self, release_url):
708
+ def download_rosa_auth_pre_signup_zip(self, release_url: str) -> str:
689
709
  headers = {"Authorization": "token " + self.token}
690
710
  r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
691
711
  r.raise_for_status()
@@ -699,7 +719,7 @@ class TerrascriptClient:
699
719
  f.write(r.content)
700
720
  return zip_file
701
721
 
702
- def get_rosa_auth_pre_token_zip(self, release_url):
722
+ def get_rosa_auth_pre_token_zip(self, release_url: str) -> str:
703
723
  if not self.rosa_auth_pre_token_zip:
704
724
  with self.rosa_auth_pre_token_zip_lock:
705
725
  # this may have already happened, so we check again
@@ -714,7 +734,7 @@ class TerrascriptClient:
714
734
  return self.rosa_auth_pre_token_zip
715
735
  return self.download_rosa_auth_pre_token_zip(release_url)
716
736
 
717
- def download_rosa_auth_pre_token_zip(self, release_url):
737
+ def download_rosa_auth_pre_token_zip(self, release_url: str) -> str:
718
738
  headers = {"Authorization": "token " + self.token}
719
739
  r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
720
740
  r.raise_for_status()
@@ -744,7 +764,7 @@ class TerrascriptClient:
744
764
  self.gitlab = GitLabApi(instance, secret_reader=self.secret_reader)
745
765
  return self.gitlab
746
766
 
747
- def init_jenkins(self, instance: dict) -> JenkinsApi:
767
+ def init_jenkins(self, instance: Mapping[str, Any]) -> JenkinsApi:
748
768
  instance_name = instance["name"]
749
769
  if not self.jenkins_map.get(instance_name):
750
770
  with self.jenkins_lock:
@@ -758,8 +778,8 @@ class TerrascriptClient:
758
778
  return self.jenkins_map[instance_name]
759
779
 
760
780
  def filter_disabled_accounts(
761
- self, accounts: Iterable[dict[str, Any]]
762
- ) -> list[dict[str, Any]]:
781
+ self, accounts: Iterable[MutableMapping[str, Any]]
782
+ ) -> list[MutableMapping[str, Any]]:
763
783
  filtered_accounts = []
764
784
  for account in accounts:
765
785
  integration = self.integration.replace("_", "-")
@@ -767,7 +787,7 @@ class TerrascriptClient:
767
787
  filtered_accounts.append(account)
768
788
  return filtered_accounts
769
789
 
770
- def populate_configs(self, accounts: Iterable[awsh.Account]):
790
+ def populate_configs(self, accounts: Iterable[awsh.Account]) -> None:
771
791
  results = threaded.run(
772
792
  awsh.get_tf_secrets,
773
793
  accounts,
@@ -781,14 +801,14 @@ class TerrascriptClient:
781
801
  config["terraformState"] = account["terraformState"]
782
802
  self.configs[account_name] = config
783
803
 
784
- def _get_partition(self, account):
804
+ def _get_partition(self, account: str) -> str:
785
805
  return self.partitions.get(account) or "aws"
786
806
 
787
807
  @staticmethod
788
- def get_tf_iam_group(group_name):
808
+ def get_tf_iam_group(group_name: str) -> aws_iam_group:
789
809
  return aws_iam_group(group_name, name=group_name)
790
810
 
791
- def get_tf_iam_user(self, user_name):
811
+ def get_tf_iam_user(self, user_name: str) -> aws_iam_user:
792
812
  return aws_iam_user(
793
813
  user_name,
794
814
  name=user_name,
@@ -796,8 +816,8 @@ class TerrascriptClient:
796
816
  tags={"managed_by_integration": self.integration},
797
817
  )
798
818
 
799
- def populate_iam_groups(self, roles):
800
- groups = {}
819
+ def populate_iam_groups(self, roles: Iterable[Role]) -> dict[str, dict[str, str]]:
820
+ groups: dict[str, dict[str, str]] = {}
801
821
  for role in roles:
802
822
  users = role["users"]
803
823
  if len(users) == 0:
@@ -840,7 +860,7 @@ class TerrascriptClient:
840
860
  return groups
841
861
 
842
862
  @staticmethod
843
- def _get_aws_username(user):
863
+ def _get_aws_username(user: Mapping[str, str]) -> str:
844
864
  return user.get("aws_username") or user["org_username"]
845
865
 
846
866
  @staticmethod
@@ -865,10 +885,10 @@ class TerrascriptClient:
865
885
 
866
886
  def populate_iam_users(
867
887
  self,
868
- roles,
869
- skip_reencrypt_accounts: list[str],
888
+ roles: Iterable[Role],
889
+ skip_reencrypt_accounts: Iterable[str],
870
890
  appsre_pgp_key: str | None,
871
- ):
891
+ ) -> bool:
872
892
  error = False
873
893
  for role in roles:
874
894
  users = role["users"]
@@ -997,10 +1017,10 @@ class TerrascriptClient:
997
1017
 
998
1018
  def populate_users(
999
1019
  self,
1000
- roles,
1001
- skip_reencrypt_accounts: list[str],
1020
+ roles: Iterable[Role],
1021
+ skip_reencrypt_accounts: Iterable[str],
1002
1022
  appsre_pgp_key: str | None = None,
1003
- ):
1023
+ ) -> bool:
1004
1024
  self.populate_iam_groups(roles)
1005
1025
  err = self.populate_iam_users(
1006
1026
  roles,
@@ -1019,7 +1039,7 @@ class TerrascriptClient:
1019
1039
 
1020
1040
  @staticmethod
1021
1041
  def get_resource_lifecycle(
1022
- common_values: dict[str, Any],
1042
+ common_values: Mapping[str, Any],
1023
1043
  ) -> dict[str, Any] | None:
1024
1044
  if lifecycle := common_values.get("lifecycle"):
1025
1045
  lifecycle = NamespaceTerraformResourceLifecycleV1(**lifecycle)
@@ -1036,7 +1056,9 @@ class TerrascriptClient:
1036
1056
  return lifecycle.dict(by_alias=True) | {"ignore_changes": ignore_changes}
1037
1057
  return None
1038
1058
 
1039
- def populate_additional_providers(self, infra_account_name: str, accounts):
1059
+ def populate_additional_providers(
1060
+ self, infra_account_name: str, accounts: Iterable[Mapping[str, Any]]
1061
+ ) -> None:
1040
1062
  for account in accounts:
1041
1063
  account_name = account["name"]
1042
1064
  assume_role = account.get("assume_role")
@@ -1067,7 +1089,7 @@ class TerrascriptClient:
1067
1089
  )
1068
1090
 
1069
1091
  def populate_route53(
1070
- self, desired_state: Iterable[dict[str, Any]], default_ttl: int = 300
1092
+ self, desired_state: Iterable[Mapping[str, Any]], default_ttl: int = 300
1071
1093
  ) -> None:
1072
1094
  for zone in desired_state:
1073
1095
  acct_name = zone["account_name"]
@@ -1086,10 +1108,10 @@ class TerrascriptClient:
1086
1108
  def populate_route53_records(
1087
1109
  self,
1088
1110
  acct_name: str,
1089
- zone: dict[str, Any],
1111
+ zone: Mapping[str, Any],
1090
1112
  zone_resource: aws_route53_zone,
1091
1113
  default_ttl: int = 300,
1092
- ):
1114
+ ) -> None:
1093
1115
  counts = {}
1094
1116
  for record in zone.get("records") or []:
1095
1117
  record_fqdn = f"{record['name']}.{zone['name']}"
@@ -1166,7 +1188,7 @@ class TerrascriptClient:
1166
1188
  record_resource = aws_route53_record(record_id, **record_values)
1167
1189
  self.add_resource(acct_name, record_resource)
1168
1190
 
1169
- def populate_vpc_peerings(self, desired_state):
1191
+ def populate_vpc_peerings(self, desired_state: Iterable[Mapping[str, Any]]) -> None:
1170
1192
  for item in desired_state:
1171
1193
  if item["deleted"]:
1172
1194
  continue
@@ -1187,7 +1209,7 @@ class TerrascriptClient:
1187
1209
 
1188
1210
  # Requester's side of the connection - the cluster's account
1189
1211
  identifier = f"{requester['vpc_id']}-{accepter['vpc_id']}"
1190
- values = {
1212
+ values: dict[str, Any] = {
1191
1213
  # adding the alias to the provider will add this resource
1192
1214
  # to the cluster's AWS account
1193
1215
  "provider": "aws." + req_alias,
@@ -1308,25 +1330,32 @@ class TerrascriptClient:
1308
1330
  "version": vpc_module_version,
1309
1331
  "name": request.identifier,
1310
1332
  "cidr": request.cidr_block.network_address,
1311
- "private_subnet_tags": {"kubernetes.io/role/internal-elb": "1"},
1312
- "public_subnet_tags": {"kubernetes.io/role/elb": "1"},
1313
1333
  "create_database_subnet_group": False,
1314
1334
  "enable_dns_hostnames": True,
1335
+ "vpc_tags": request.vpc_tags or {},
1315
1336
  "tags": {
1316
1337
  "managed_by_integration": self.integration,
1317
1338
  },
1318
1339
  }
1319
1340
 
1320
- if request.subnets and request.subnets.public:
1321
- vpc_module_values["public_subnets"] = request.subnets.public
1322
- if request.subnets and request.subnets.private:
1323
- vpc_module_values["private_subnets"] = request.subnets.private
1324
- if request.subnets and request.subnets.availability_zones:
1325
- vpc_module_values["azs"] = request.subnets.availability_zones
1326
-
1327
- # We only want to enable nat_gateway if we have public and private subnets
1328
- if request.subnets and request.subnets.public and request.subnets.private:
1329
- vpc_module_values["enable_nat_gateway"] = True
1341
+ if request.subnets:
1342
+ if request.subnets.public:
1343
+ vpc_module_values["public_subnets"] = request.subnets.public
1344
+ vpc_module_values["public_subnet_tags"] = (
1345
+ VPC_REQUEST_DEFAULT_PUBLIC_SUBNET_TAGS
1346
+ | (request.subnets.public_subnet_tags or {})
1347
+ )
1348
+ if request.subnets.private:
1349
+ vpc_module_values["private_subnets"] = request.subnets.private
1350
+ vpc_module_values["private_subnet_tags"] = (
1351
+ VPC_REQUEST_DEFAULT_PRIVATE_SUBNET_TAGS
1352
+ | (request.subnets.private_subnet_tags or {})
1353
+ )
1354
+ if request.subnets.availability_zones:
1355
+ vpc_module_values["azs"] = request.subnets.availability_zones
1356
+ # We only want to enable nat_gateway if we have public and private subnets
1357
+ if request.subnets.public and request.subnets.private:
1358
+ vpc_module_values["enable_nat_gateway"] = True
1330
1359
 
1331
1360
  aws_account = request.account.name
1332
1361
  vpc_module = Module(request.identifier, **vpc_module_values)
@@ -1367,21 +1396,24 @@ class TerrascriptClient:
1367
1396
  )
1368
1397
  self.add_resource(aws_account, vpc_cidr_block_output)
1369
1398
 
1370
- if request.subnets and request.subnets.private:
1371
- private_subnets_output = Output(
1372
- f"{request.identifier}-private_subnets",
1373
- value=f"${{module.{request.identifier}.private_subnets}}",
1374
- )
1375
- self.add_resource(aws_account, private_subnets_output)
1399
+ if request.subnets:
1400
+ if request.subnets.private:
1401
+ private_subnets_output = Output(
1402
+ f"{request.identifier}-private_subnets",
1403
+ value=f"${{module.{request.identifier}.private_subnets}}",
1404
+ )
1405
+ self.add_resource(aws_account, private_subnets_output)
1376
1406
 
1377
- if request.subnets and request.subnets.public:
1378
- public_subnets_output = Output(
1379
- f"{request.identifier}-public_subnets",
1380
- value=f"${{module.{request.identifier}.public_subnets}}",
1381
- )
1382
- self.add_resource(aws_account, public_subnets_output)
1407
+ if request.subnets.public:
1408
+ public_subnets_output = Output(
1409
+ f"{request.identifier}-public_subnets",
1410
+ value=f"${{module.{request.identifier}.public_subnets}}",
1411
+ )
1412
+ self.add_resource(aws_account, public_subnets_output)
1383
1413
 
1384
- def populate_tgw_attachments(self, desired_state):
1414
+ def populate_tgw_attachments(
1415
+ self, desired_state: Iterable[DesiredStateItem]
1416
+ ) -> None:
1385
1417
  for item in desired_state:
1386
1418
  if item.deleted:
1387
1419
  continue
@@ -1404,30 +1436,32 @@ class TerrascriptClient:
1404
1436
 
1405
1437
  tags = {"managed_by_integration": self.integration, "Name": connection_name}
1406
1438
  # add resource share
1407
- values = {
1439
+ values_share: dict[str, Any] = {
1408
1440
  "name": connection_name,
1409
1441
  "allow_external_principals": True,
1410
1442
  "tags": tags,
1411
1443
  }
1412
1444
  if self._multiregion_account(req_account_name):
1413
- values["provider"] = "aws." + requester.region
1414
- tf_resource_share = aws_ram_resource_share(connection_name, **values)
1445
+ values_share["provider"] = "aws." + requester.region
1446
+ tf_resource_share = aws_ram_resource_share(connection_name, **values_share)
1415
1447
  self.add_resource(infra_account_name, tf_resource_share)
1416
1448
 
1417
1449
  # share with accepter aws account
1418
- values = {
1450
+ values_resource_principal_association: dict[str, str] = {
1419
1451
  "principal": acc_uid,
1420
1452
  "resource_share_arn": "${" + tf_resource_share.arn + "}",
1421
1453
  }
1422
1454
  if self._multiregion_account(req_account_name):
1423
- values["provider"] = "aws." + requester.region
1424
- tf_resource_association = aws_ram_principal_association(
1425
- connection_name, **values
1455
+ values_resource_principal_association["provider"] = (
1456
+ "aws." + requester.region
1457
+ )
1458
+ tf_resource_principal_association = aws_ram_principal_association(
1459
+ connection_name, **values_resource_principal_association
1426
1460
  )
1427
- self.add_resource(infra_account_name, tf_resource_association)
1461
+ self.add_resource(infra_account_name, tf_resource_principal_association)
1428
1462
 
1429
1463
  # accept resource share from accepter aws account
1430
- values = {
1464
+ values_share_resource_accepter: dict[str, Any] = {
1431
1465
  "provider": "aws." + acc_alias,
1432
1466
  "share_arn": "${" + tf_resource_share.arn + "}",
1433
1467
  "depends_on": [
@@ -1436,7 +1470,7 @@ class TerrascriptClient:
1436
1470
  ],
1437
1471
  }
1438
1472
  tf_resource_share_accepter = aws_ram_resource_share_accepter(
1439
- connection_name, **values
1473
+ connection_name, **values_share_resource_accepter
1440
1474
  )
1441
1475
  self.add_resource(infra_account_name, tf_resource_share_accepter)
1442
1476
 
@@ -1446,20 +1480,23 @@ class TerrascriptClient:
1446
1480
 
1447
1481
  # tgw share association
1448
1482
  identifier = f"{requester.tgw_id}-{accepter.vpc_id}"
1449
- values = {
1483
+ values_resource_association: dict[str, str] = {
1450
1484
  "resource_arn": requester.tgw_arn,
1451
1485
  "resource_share_arn": "${" + tf_resource_share.arn + "}",
1452
1486
  }
1453
1487
  if self._multiregion_account(req_account_name):
1454
- values["provider"] = "aws." + requester.region
1455
- tf_resource_association = aws_ram_resource_association(identifier, **values)
1488
+ values_resource_association["provider"] = "aws." + requester.region
1489
+ tf_resource_association = aws_ram_resource_association(
1490
+ identifier, **values_resource_association
1491
+ )
1456
1492
  self.add_resource(infra_account_name, tf_resource_association)
1457
1493
 
1458
1494
  # now that the tgw is shared to the cluster's aws account
1459
1495
  # we can create a vpc attachment to the tgw
1460
1496
  subnets_id_az = accepter.subnets_id_az
1497
+ assert subnets_id_az is not None # make mypy happy
1461
1498
  subnets = self.get_az_unique_subnet_ids(subnets_id_az)
1462
- values = {
1499
+ values_resource_attachment: dict[str, Any] = {
1463
1500
  "provider": "aws." + acc_alias,
1464
1501
  "subnet_ids": subnets,
1465
1502
  "transit_gateway_id": requester.tgw_id,
@@ -1471,20 +1508,22 @@ class TerrascriptClient:
1471
1508
  "tags": tags,
1472
1509
  }
1473
1510
  tf_resource_attachment = aws_ec2_transit_gateway_vpc_attachment(
1474
- identifier, **values
1511
+ identifier, **values_resource_attachment
1475
1512
  )
1476
1513
  # we send the attachment from the cluster's aws account
1477
1514
  self.add_resource(infra_account_name, tf_resource_attachment)
1478
1515
 
1479
1516
  # and accept the attachment in the non cluster's aws account
1480
- values = {
1517
+ values_attachment_accepter = {
1481
1518
  "transit_gateway_attachment_id": "${" + tf_resource_attachment.id + "}",
1482
1519
  "tags": tags,
1483
1520
  }
1484
1521
  if self._multiregion_account(req_account_name):
1485
- values["provider"] = "aws." + requester.region
1522
+ values_attachment_accepter["provider"] = "aws." + requester.region
1486
1523
  tf_resource_attachment_accepter = (
1487
- aws_ec2_transit_gateway_vpc_attachment_accepter(identifier, **values)
1524
+ aws_ec2_transit_gateway_vpc_attachment_accepter(
1525
+ identifier, **values_attachment_accepter
1526
+ )
1488
1527
  )
1489
1528
  self.add_resource(infra_account_name, tf_resource_attachment_accepter)
1490
1529
 
@@ -1530,16 +1569,16 @@ class TerrascriptClient:
1530
1569
  + f"unsupported region: {route_region}"
1531
1570
  )
1532
1571
  continue
1533
- values = {
1572
+ values_gateway_router = {
1534
1573
  "destination_cidr_block": route["cidr_block"],
1535
1574
  "transit_gateway_attachment_id": route["tgw_attachment_id"],
1536
1575
  "transit_gateway_route_table_id": route["tgw_route_table_id"],
1537
1576
  }
1538
1577
  if self._multiregion_account(req_account_name):
1539
- values["provider"] = "aws." + route_region
1578
+ values_gateway_router["provider"] = "aws." + route_region
1540
1579
  route_identifier = f"{identifier}-{route['tgw_id']}"
1541
1580
  tf_resource = aws_ec2_transit_gateway_route(
1542
- route_identifier, **values
1581
+ route_identifier, **values_gateway_router
1543
1582
  )
1544
1583
  self.add_resource(infra_account_name, tf_resource)
1545
1584
 
@@ -1569,7 +1608,7 @@ class TerrascriptClient:
1569
1608
  + f"unsupported region: {rule_region}"
1570
1609
  )
1571
1610
  continue
1572
- values = {
1611
+ values_rule = {
1573
1612
  "type": "ingress",
1574
1613
  "from_port": 0,
1575
1614
  "to_port": 0,
@@ -1578,31 +1617,37 @@ class TerrascriptClient:
1578
1617
  "security_group_id": rule["security_group_id"],
1579
1618
  }
1580
1619
  if self._multiregion_account(req_account_name):
1581
- values["provider"] = "aws." + rule_region
1620
+ values_rule["provider"] = "aws." + rule_region
1582
1621
  rule_identifier = f"{identifier}-{rule['vpc_id']}"
1583
- tf_resource = aws_security_group_rule(rule_identifier, **values)
1622
+ tf_resource = aws_security_group_rule(
1623
+ rule_identifier, **values_rule
1624
+ )
1584
1625
  self.add_resource(infra_account_name, tf_resource)
1585
1626
 
1586
1627
  for zone in requester.hostedzones or []:
1587
1628
  id = f"{identifier}-{zone}"
1588
- values = {
1629
+ values_authorization = {
1589
1630
  "vpc_id": accepter.vpc_id,
1590
1631
  "vpc_region": accepter.region,
1591
1632
  "zone_id": zone,
1592
1633
  }
1593
- authorization = aws_route53_vpc_association_authorization(id, **values)
1634
+ authorization = aws_route53_vpc_association_authorization(
1635
+ id, **values_authorization
1636
+ )
1594
1637
  self.add_resource(infra_account_name, authorization)
1595
- values = {
1638
+ values_association = {
1596
1639
  "provider": "aws." + acc_alias,
1597
1640
  "vpc_id": f"${{aws_route53_vpc_association_authorization.{id}.vpc_id}}",
1598
1641
  "vpc_region": accepter.region,
1599
1642
  "zone_id": f"${{aws_route53_vpc_association_authorization.{id}.zone_id}}",
1600
1643
  }
1601
- association = aws_route53_zone_association(id, **values)
1644
+ association = aws_route53_zone_association(id, **values_association)
1602
1645
  self.add_resource(infra_account_name, association)
1603
1646
 
1604
1647
  @staticmethod
1605
- def get_az_unique_subnet_ids(subnets_id_az):
1648
+ def get_az_unique_subnet_ids(
1649
+ subnets_id_az: Iterable[Mapping[str, str]],
1650
+ ) -> list[str]:
1606
1651
  """returns a list of subnet ids which are unique per az"""
1607
1652
  results = []
1608
1653
  azs = []
@@ -1710,7 +1755,9 @@ class TerrascriptClient:
1710
1755
 
1711
1756
  self.resource_spec_inventory[spec.id_object()] = spec
1712
1757
 
1713
- def populate_tf_resources(self, spec, ocm_map=None):
1758
+ def populate_tf_resources(
1759
+ self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
1760
+ ) -> None:
1714
1761
  if spec.provision_provider != PROVIDER_AWS:
1715
1762
  raise UnknownProviderError(spec.provision_provider)
1716
1763
 
@@ -1769,13 +1816,13 @@ class TerrascriptClient:
1769
1816
  else:
1770
1817
  raise UnknownProviderError(provider)
1771
1818
 
1772
- def populate_tf_resource_rds(self, spec):
1819
+ def populate_tf_resource_rds(self, spec: ExternalResourceSpec) -> None:
1773
1820
  account = spec.provisioner_name
1774
1821
  identifier = spec.identifier
1775
1822
  values = self.init_values(spec)
1776
1823
  output_prefix = spec.output_prefix
1777
1824
 
1778
- tf_resources = []
1825
+ tf_resources: list[TFResource] = []
1779
1826
  self.init_common_outputs(tf_resources, spec)
1780
1827
 
1781
1828
  # we want to allow an empty name, so we
@@ -1804,7 +1851,9 @@ class TerrascriptClient:
1804
1851
  # To get the provider we should use, we get the region
1805
1852
  # and use that as an alias in the provider definition
1806
1853
  if az:
1807
- provider = "aws." + self._region_from_availability_zone(az)
1854
+ region_az = self._region_from_availability_zone(az)
1855
+ assert region_az # make mypy happy
1856
+ provider = "aws." + region_az
1808
1857
  values["provider"] = provider
1809
1858
  if region:
1810
1859
  provider_region = f"aws.{region}"
@@ -1844,7 +1893,7 @@ class TerrascriptClient:
1844
1893
  # 'deps' should contain a list of terraform resource names
1845
1894
  # (not full objects) that must be created
1846
1895
  # before the actual RDS instance should be created
1847
- deps = []
1896
+ deps: list[str] = []
1848
1897
 
1849
1898
  parameter_group = values.pop("parameter_group", None)
1850
1899
  if parameter_group:
@@ -1905,14 +1954,14 @@ class TerrascriptClient:
1905
1954
  role_res_name = self.get_dependencies([role_tf_resource])[0]
1906
1955
  deps.append(role_res_name)
1907
1956
 
1908
- em_values = {
1957
+ em_values_attachment: dict[str, Any] = {
1909
1958
  "role": role_tf_resource.name,
1910
1959
  "policy_arn": f"arn:{self._get_partition(account)}:iam::aws:policy/service-role/"
1911
1960
  + "AmazonRDSEnhancedMonitoringRole",
1912
1961
  "depends_on": self.get_dependencies([role_tf_resource]),
1913
1962
  }
1914
1963
  attachment_tf_resource = aws_iam_role_policy_attachment(
1915
- em_identifier, **em_values
1964
+ em_identifier, **em_values_attachment
1916
1965
  )
1917
1966
  tf_resources.append(attachment_tf_resource)
1918
1967
 
@@ -1930,9 +1979,8 @@ class TerrascriptClient:
1930
1979
  if reset_password:
1931
1980
  password = self.generate_random_password()
1932
1981
  else:
1933
- password = spec.get_secret_field("db.password")
1934
- if not password:
1935
- password = self.generate_random_password()
1982
+ db_password = spec.get_secret_field("db.password")
1983
+ password = db_password or self.generate_random_password()
1936
1984
  else:
1937
1985
  password = ""
1938
1986
  values["password"] = password
@@ -2024,7 +2072,7 @@ class TerrascriptClient:
2024
2072
  # to a provider version with this bug fix.
2025
2073
  # https://github.com/hashicorp/terraform-provider-aws/pull/20926
2026
2074
  if enhanced_monitoring and replica_source:
2027
- sleep_vals = {}
2075
+ sleep_vals: dict[str, Any] = {}
2028
2076
  sleep_vals["depends_on"] = [attachment_res_name]
2029
2077
  sleep_vals["create_duration"] = "30s"
2030
2078
 
@@ -2117,7 +2165,7 @@ class TerrascriptClient:
2117
2165
 
2118
2166
  self.add_resources(account, tf_resources)
2119
2167
 
2120
- def _multiregion_account(self, name):
2168
+ def _multiregion_account(self, name: str) -> bool:
2121
2169
  if name not in self.configs:
2122
2170
  return False
2123
2171
 
@@ -2134,11 +2182,11 @@ class TerrascriptClient:
2134
2182
  return spec
2135
2183
  return None
2136
2184
 
2137
- def _get_db_name_from_values(self, values: dict) -> str:
2185
+ def _get_db_name_from_values(self, values: Mapping[str, Any]) -> str:
2138
2186
  return values.get("name") or values.get("db_name") or ""
2139
2187
 
2140
2188
  @staticmethod
2141
- def _region_from_availability_zone(az):
2189
+ def _region_from_availability_zone(az: str) -> str | None:
2142
2190
  # Find the region by removing the last character from the
2143
2191
  # availability zone. Availability zone is defined like
2144
2192
  # us-east-1a, us-east-1b, etc. If there is no availability
@@ -2148,39 +2196,38 @@ class TerrascriptClient:
2148
2196
  return None
2149
2197
 
2150
2198
  @staticmethod
2151
- def _db_needs_auth(config):
2152
- return bool(
2153
- "replicate_source_db" not in config
2154
- and config.get("replica_source", None) is None
2199
+ def _db_needs_auth(config: Mapping[str, Any]) -> bool:
2200
+ return (
2201
+ "replicate_source_db" not in config and config.get("replica_source") is None
2155
2202
  )
2156
2203
 
2157
2204
  @staticmethod
2158
- def validate_db_name(name):
2205
+ def validate_db_name(name: str) -> bool:
2159
2206
  """Handle for Error creating DB Instance:
2160
2207
  InvalidParameterValue: DBName must begin with a letter
2161
2208
  and contain only alphanumeric characters."""
2162
2209
  pattern = r"^[a-zA-Z][a-zA-Z0-9_]+$"
2163
- return re.search(pattern, name) and len(name) < 64
2210
+ return len(name) < 64 and re.search(pattern, name) is not None
2164
2211
 
2165
2212
  @staticmethod
2166
- def generate_random_password(string_length=20):
2213
+ def generate_random_password(string_length: int = 20) -> str:
2167
2214
  """Generate a random string of letters and digits"""
2168
2215
  letters_and_digits = string.ascii_letters + string.digits
2169
2216
  return "".join(random.choice(letters_and_digits) for i in range(string_length))
2170
2217
 
2171
- def populate_tf_resource_s3(self, spec):
2218
+ def populate_tf_resource_s3(self, spec: ExternalResourceSpec) -> aws_s3_bucket:
2172
2219
  account = spec.provisioner_name
2173
2220
  identifier = spec.identifier
2174
2221
  common_values = self.init_values(spec)
2175
2222
  output_prefix = spec.output_prefix
2176
2223
 
2177
- tf_resources = []
2224
+ tf_resources: list[TFResource] = []
2178
2225
  self.init_common_outputs(tf_resources, spec)
2179
2226
 
2180
2227
  # s3 bucket
2181
2228
  # Terraform resource reference:
2182
2229
  # https://www.terraform.io/docs/providers/aws/r/s3_bucket.html
2183
- values = {}
2230
+ values: dict[str, Any] = {}
2184
2231
  values["bucket"] = identifier
2185
2232
  versioning = common_values.get("versioning", True)
2186
2233
  values["versioning"] = {"enabled": versioning}
@@ -2307,7 +2354,7 @@ class TerrascriptClient:
2307
2354
 
2308
2355
  rc_values.clear()
2309
2356
  rc_values["name"] = config["rule_name"] + "_iam_policy"
2310
- policy = {
2357
+ policy: dict[str, Any] = {
2311
2358
  "Version": "2012-10-17",
2312
2359
  "Statement": [
2313
2360
  {
@@ -2374,6 +2421,7 @@ class TerrascriptClient:
2374
2421
  if len(deps) > 0:
2375
2422
  values["depends_on"] = self.get_dependencies(deps)
2376
2423
  region = common_values.get("region") or self.default_regions.get(account)
2424
+ assert region # make mypy happy
2377
2425
  if self._multiregion_account(account):
2378
2426
  values["provider"] = "aws." + region
2379
2427
  bucket_tf_resource = aws_s3_bucket(identifier, **values)
@@ -2508,10 +2556,12 @@ class TerrascriptClient:
2508
2556
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
2509
2557
 
2510
2558
  # iam user for bucket
2511
- values = {}
2512
- values["name"] = identifier
2513
- values["tags"] = common_values["tags"]
2514
- values["depends_on"] = self.get_dependencies([bucket_tf_resource])
2559
+ values = {
2560
+ "name": identifier,
2561
+ "tags": common_values["tags"],
2562
+ "depends_on": self.get_dependencies([bucket_tf_resource]),
2563
+ }
2564
+
2515
2565
  user_tf_resource = aws_iam_user(identifier, **values)
2516
2566
  tf_resources.append(user_tf_resource)
2517
2567
 
@@ -2521,8 +2571,7 @@ class TerrascriptClient:
2521
2571
  )
2522
2572
 
2523
2573
  # iam user policy for bucket
2524
- values = {}
2525
- values["name"] = identifier
2574
+ values = {"name": identifier}
2526
2575
 
2527
2576
  action = ["s3:*Object*"]
2528
2577
  if common_values.get("acl", "private") == "public-read":
@@ -2566,7 +2615,7 @@ class TerrascriptClient:
2566
2615
 
2567
2616
  return bucket_tf_resource
2568
2617
 
2569
- def populate_tf_resource_elasticache(self, spec):
2618
+ def populate_tf_resource_elasticache(self, spec: ExternalResourceSpec) -> None:
2570
2619
  account = spec.provisioner_name
2571
2620
  identifier = spec.identifier
2572
2621
  values = self.init_values(spec)
@@ -2574,7 +2623,7 @@ class TerrascriptClient:
2574
2623
  values.setdefault("replication_group_id", values["identifier"])
2575
2624
  values.pop("identifier", None)
2576
2625
 
2577
- tf_resources = []
2626
+ tf_resources: list[TFResource] = []
2578
2627
  self.init_common_outputs(tf_resources, spec)
2579
2628
 
2580
2629
  default_region = self.default_regions.get(account)
@@ -2654,19 +2703,23 @@ class TerrascriptClient:
2654
2703
 
2655
2704
  self.add_resources(account, tf_resources)
2656
2705
 
2657
- def populate_tf_resource_service_account(self, spec, ocm_map=None):
2706
+ def populate_tf_resource_service_account(
2707
+ self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
2708
+ ) -> None:
2658
2709
  account = spec.provisioner_name
2659
2710
  identifier = spec.identifier
2660
2711
  common_values = self.init_values(spec)
2661
2712
  output_prefix = spec.output_prefix
2662
2713
 
2663
- tf_resources = []
2714
+ tf_resources: list[TFResource] = []
2664
2715
  self.init_common_outputs(tf_resources, spec)
2665
2716
 
2666
2717
  # iam user for bucket
2667
- values = {}
2668
- values["name"] = identifier
2669
- values["tags"] = common_values["tags"]
2718
+ values = {
2719
+ "name": identifier,
2720
+ "tags": common_values["tags"],
2721
+ }
2722
+
2670
2723
  user_tf_resource = aws_iam_user(identifier, **values)
2671
2724
  tf_resources.append(user_tf_resource)
2672
2725
 
@@ -2750,13 +2803,15 @@ class TerrascriptClient:
2750
2803
 
2751
2804
  self.add_resources(account, tf_resources)
2752
2805
 
2753
- def populate_tf_resource_secrets_manager_sa(self, spec):
2806
+ def populate_tf_resource_secrets_manager_sa(
2807
+ self, spec: ExternalResourceSpec
2808
+ ) -> None:
2754
2809
  account = spec.provisioner_name
2755
2810
  identifier = spec.identifier
2756
2811
  common_values = self.init_values(spec)
2757
2812
  output_prefix = spec.output_prefix
2758
2813
 
2759
- tf_resources = []
2814
+ tf_resources: list[TFResource] = []
2760
2815
  self.init_common_outputs(tf_resources, spec)
2761
2816
 
2762
2817
  secrets_prefix = common_values["secrets_prefix"]
@@ -2780,7 +2835,7 @@ class TerrascriptClient:
2780
2835
 
2781
2836
  tf_resources.extend(
2782
2837
  self.get_tf_iam_service_user(
2783
- [], identifier, policy, common_values["tags"], output_prefix
2838
+ None, identifier, policy, common_values["tags"], output_prefix
2784
2839
  )
2785
2840
  )
2786
2841
 
@@ -2790,20 +2845,20 @@ class TerrascriptClient:
2790
2845
 
2791
2846
  self.add_resources(account, tf_resources)
2792
2847
 
2793
- def populate_tf_resource_role(self, spec):
2848
+ def populate_tf_resource_role(self, spec: ExternalResourceSpec) -> None:
2794
2849
  account = spec.provisioner_name
2795
2850
  identifier = spec.identifier
2796
2851
  common_values = self.init_values(spec)
2797
2852
  output_prefix = spec.output_prefix
2798
2853
 
2799
- tf_resources = []
2854
+ tf_resources: list[TFResource] = []
2800
2855
  self.init_common_outputs(tf_resources, spec)
2801
2856
 
2802
2857
  assume_role = common_values["assume_role"]
2803
2858
  assume_role = {k: v for k, v in assume_role.items() if v is not None}
2804
2859
  assume_action = common_values.get("assume_action") or "AssumeRole"
2805
2860
  # assume role policy
2806
- assume_role_policy = {
2861
+ assume_role_policy: dict[str, Any] = {
2807
2862
  "Version": "2012-10-17",
2808
2863
  "Statement": [
2809
2864
  {
@@ -2818,7 +2873,7 @@ class TerrascriptClient:
2818
2873
  assume_role_policy["Statement"][0]["Condition"] = assume_condition
2819
2874
 
2820
2875
  # iam role
2821
- values = {
2876
+ values: dict[str, Any] = {
2822
2877
  "name": identifier,
2823
2878
  "tags": common_values["tags"],
2824
2879
  "assume_role_policy": json.dumps(assume_role_policy),
@@ -2871,7 +2926,9 @@ class TerrascriptClient:
2871
2926
 
2872
2927
  self.add_resources(account, tf_resources)
2873
2928
 
2874
- def populate_iam_policy(self, account: str, name: str, policy: dict[str, Any]):
2929
+ def populate_iam_policy(
2930
+ self, account: str, name: str, policy: Mapping[str, Any]
2931
+ ) -> None:
2875
2932
  tf_aws_iam_policy = aws_iam_policy(
2876
2933
  f"{account}-{name}", name=name, policy=json.dumps(policy)
2877
2934
  )
@@ -2882,8 +2939,8 @@ class TerrascriptClient:
2882
2939
  account: str,
2883
2940
  name: str,
2884
2941
  saml_provider_name: str,
2885
- aws_managed_policies: list[str],
2886
- customer_managed_policies: list[str] | None = None,
2942
+ aws_managed_policies: Iterable[str],
2943
+ customer_managed_policies: Iterable[str] | None = None,
2887
2944
  max_session_duration_hours: int = 1,
2888
2945
  ) -> None:
2889
2946
  """Manage the an IAM role needed for SAML authentication."""
@@ -2921,17 +2978,19 @@ class TerrascriptClient:
2921
2978
  )
2922
2979
  self.add_resource(account, role_tf_resource)
2923
2980
 
2924
- def populate_tf_resource_sqs(self, spec):
2981
+ def populate_tf_resource_sqs(self, spec: ExternalResourceSpec) -> None:
2925
2982
  account = spec.provisioner_name
2926
2983
  identifier = spec.identifier
2927
2984
  common_values = self.init_values(spec)
2928
2985
  output_prefix = spec.output_prefix
2929
2986
  uid = self.uids.get(account)
2930
2987
 
2931
- tf_resources = []
2988
+ tf_resources: list[TFResource] = []
2932
2989
  self.init_common_outputs(tf_resources, spec)
2933
2990
  region = common_values.get("region") or self.default_regions.get(account)
2991
+ assert region # make mypy happy
2934
2992
  specs = common_values.get("specs")
2993
+ assert specs is not None # make mypy happy
2935
2994
  all_queues_per_spec = []
2936
2995
  kms_keys = set()
2937
2996
  for _spec in specs:
@@ -3005,9 +3064,11 @@ class TerrascriptClient:
3005
3064
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
3006
3065
 
3007
3066
  # iam user for queue
3008
- values = {}
3009
- values["name"] = identifier
3010
- values["tags"] = common_values["tags"]
3067
+ values = {
3068
+ "name": identifier,
3069
+ "tags": common_values["tags"],
3070
+ }
3071
+
3011
3072
  user_tf_resource = aws_iam_user(identifier, **values)
3012
3073
  tf_resources.append(user_tf_resource)
3013
3074
 
@@ -3021,9 +3082,9 @@ class TerrascriptClient:
3021
3082
  policy_identifier = f"{identifier}-{policy_index}"
3022
3083
  if len(all_queues_per_spec) == 1:
3023
3084
  policy_identifier = identifier
3024
- values = {}
3025
- values["name"] = policy_identifier
3026
- policy = {
3085
+ values = {"name": policy_identifier}
3086
+
3087
+ policy: dict[str, Any] = {
3027
3088
  "Version": "2012-10-17",
3028
3089
  "Statement": [
3029
3090
  {
@@ -3049,27 +3110,29 @@ class TerrascriptClient:
3049
3110
  tf_resources.append(policy_tf_resource)
3050
3111
 
3051
3112
  # iam user policy attachment
3052
- values = {}
3053
- values["user"] = identifier
3054
- values["policy_arn"] = "${" + policy_tf_resource.arn + "}"
3055
- values["depends_on"] = self.get_dependencies([
3056
- user_tf_resource,
3057
- policy_tf_resource,
3058
- ])
3113
+ values = {
3114
+ "user": identifier,
3115
+ "policy_arn": "${" + policy_tf_resource.arn + "}",
3116
+ "depends_on": self.get_dependencies([
3117
+ user_tf_resource,
3118
+ policy_tf_resource,
3119
+ ]),
3120
+ }
3121
+
3059
3122
  tf_resource = aws_iam_user_policy_attachment(policy_identifier, **values)
3060
3123
  tf_resources.append(tf_resource)
3061
3124
 
3062
3125
  self.add_resources(account, tf_resources)
3063
3126
 
3064
- def populate_tf_resource_sns(self, spec):
3127
+ def populate_tf_resource_sns(self, spec: ExternalResourceSpec) -> None:
3065
3128
  account = spec.provisioner_name
3066
3129
  identifier = spec.identifier
3067
3130
  common_values = self.init_values(spec)
3068
3131
  output_prefix = spec.output_prefix
3069
3132
  policy = common_values.get("inline_policy")
3070
3133
  region = common_values.get("region") or self.default_regions.get(account)
3071
-
3072
- values = {}
3134
+ assert region # make mypy happy
3135
+ values: dict[str, Any] = {}
3073
3136
  fifo_topic = common_values.get("fifo_topic", False)
3074
3137
  topic_name = identifier + ".fifo" if fifo_topic else identifier
3075
3138
 
@@ -3077,16 +3140,18 @@ class TerrascriptClient:
3077
3140
  values["policy"] = policy
3078
3141
  values["fifo_topic"] = fifo_topic
3079
3142
 
3080
- tf_resources = []
3143
+ tf_resources: list[TFResource] = []
3081
3144
  self.init_common_outputs(tf_resources, spec)
3082
3145
  tf_resource = aws_sns_topic(identifier, **values)
3083
3146
  tf_resources.append(tf_resource)
3084
3147
 
3085
3148
  if "subscriptions" in common_values:
3086
- subscriptions = common_values.get("subscriptions")
3149
+ subscriptions = common_values["subscriptions"]
3087
3150
  for index, sub in enumerate(subscriptions):
3088
- sub_values = {}
3089
- sub_values["topic_arn"] = "${aws_sns_topic" + "." + identifier + ".arn}"
3151
+ sub_values = {
3152
+ "topic_arn": "${aws_sns_topic" + "." + identifier + ".arn}"
3153
+ }
3154
+
3090
3155
  protocol = sub["protocol"]
3091
3156
  endpoint = sub["endpoint"]
3092
3157
  if protocol == "email" and not EMAIL_REGEX.match(endpoint):
@@ -3111,17 +3176,19 @@ class TerrascriptClient:
3111
3176
  tf_resources.append(Output(output_name, value=output_value))
3112
3177
  self.add_resources(account, tf_resources)
3113
3178
 
3114
- def populate_tf_resource_dynamodb(self, spec):
3179
+ def populate_tf_resource_dynamodb(self, spec: ExternalResourceSpec) -> None:
3115
3180
  account = spec.provisioner_name
3116
3181
  identifier = spec.identifier
3117
3182
  common_values = self.init_values(spec)
3118
3183
  output_prefix = spec.output_prefix
3119
3184
  uid = self.uids.get(account)
3120
3185
 
3121
- tf_resources = []
3186
+ tf_resources: list[TFResource] = []
3122
3187
  self.init_common_outputs(tf_resources, spec)
3123
3188
  region = common_values.get("region") or self.default_regions.get(account)
3189
+ assert region # make mypy happy
3124
3190
  specs = common_values.get("specs")
3191
+ assert specs is not None # make mypy happy
3125
3192
  all_tables = []
3126
3193
  for _spec in specs:
3127
3194
  defaults = self.get_values(_spec["defaults"])
@@ -3135,9 +3202,11 @@ class TerrascriptClient:
3135
3202
  # Terraform resource reference:
3136
3203
  # https://www.terraform.io/docs/providers/aws/r/
3137
3204
  # dynamodb_table.html
3138
- values = {}
3139
- values["name"] = table
3140
- values["tags"] = common_values["tags"]
3205
+ values = {
3206
+ "name": table,
3207
+ "tags": common_values["tags"],
3208
+ }
3209
+
3141
3210
  values.update(defaults)
3142
3211
  values["attribute"] = attributes
3143
3212
  if self._multiregion_account(account):
@@ -3158,9 +3227,11 @@ class TerrascriptClient:
3158
3227
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
3159
3228
 
3160
3229
  # iam user for table
3161
- values = {}
3162
- values["name"] = identifier
3163
- values["tags"] = common_values["tags"]
3230
+ values = {
3231
+ "name": identifier,
3232
+ "tags": common_values["tags"],
3233
+ }
3234
+
3164
3235
  user_tf_resource = aws_iam_user(identifier, **values)
3165
3236
  tf_resources.append(user_tf_resource)
3166
3237
 
@@ -3200,23 +3271,24 @@ class TerrascriptClient:
3200
3271
 
3201
3272
  self.add_resources(account, tf_resources)
3202
3273
 
3203
- def populate_tf_resource_ecr(self, spec):
3274
+ def populate_tf_resource_ecr(self, spec: ExternalResourceSpec) -> None:
3204
3275
  account = spec.provisioner_name
3205
3276
  identifier = spec.identifier
3206
3277
  common_values = self.init_values(spec)
3207
3278
  output_prefix = spec.output_prefix
3208
3279
 
3209
- tf_resources = []
3280
+ tf_resources: list[TFResource] = []
3210
3281
  self.init_common_outputs(tf_resources, spec)
3211
3282
 
3212
3283
  # ecr repository
3213
3284
  # Terraform resource reference:
3214
3285
  # https://www.terraform.io/docs/providers/aws/r/ecr_repository.html
3215
- values = {}
3286
+ values: dict[str, Any] = {}
3216
3287
  values["name"] = identifier
3217
3288
  values["tags"] = common_values["tags"]
3218
3289
 
3219
3290
  region = common_values.get("region") or self.default_regions.get(account)
3291
+ assert region # make mypy happy
3220
3292
  if self._multiregion_account(account):
3221
3293
  values["provider"] = "aws." + region
3222
3294
  ecr_tf_resource = aws_ecr_repository(identifier, **values)
@@ -3242,11 +3314,12 @@ class TerrascriptClient:
3242
3314
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
3243
3315
 
3244
3316
  # iam user for repository
3245
- values = {}
3246
- values["name"] = identifier
3247
- values["tags"] = common_values["tags"]
3248
- values["depends_on"] = self.get_dependencies([ecr_tf_resource])
3249
- user_tf_resource = aws_iam_user(identifier, **values)
3317
+ values_iam_user: dict[str, Any] = {
3318
+ "name": identifier,
3319
+ "tags": common_values["tags"],
3320
+ "depends_on": self.get_dependencies([ecr_tf_resource]),
3321
+ }
3322
+ user_tf_resource = aws_iam_user(identifier, **values_iam_user)
3250
3323
  tf_resources.append(user_tf_resource)
3251
3324
 
3252
3325
  # iam access key for user
@@ -3255,8 +3328,7 @@ class TerrascriptClient:
3255
3328
  )
3256
3329
 
3257
3330
  # iam user policy for bucket
3258
- values = {}
3259
- values["name"] = identifier
3331
+ values_policy: dict[str, Any] = {"name": identifier}
3260
3332
  policy = {
3261
3333
  "Version": "2012-10-17",
3262
3334
  "Statement": [
@@ -3293,10 +3365,10 @@ class TerrascriptClient:
3293
3365
  },
3294
3366
  ],
3295
3367
  }
3296
- values["policy"] = json.dumps(policy, sort_keys=True)
3297
- values["depends_on"] = self.get_dependencies([user_tf_resource])
3368
+ values_policy["policy"] = json.dumps(policy, sort_keys=True)
3369
+ values_policy["depends_on"] = self.get_dependencies([user_tf_resource])
3298
3370
 
3299
- tf_aws_iam_policy = aws_iam_policy(identifier, **values)
3371
+ tf_aws_iam_policy = aws_iam_policy(identifier, **values_policy)
3300
3372
  tf_resources.append(tf_aws_iam_policy)
3301
3373
 
3302
3374
  tf_aws_iam_user_policy_attachment = aws_iam_user_policy_attachment(
@@ -3309,7 +3381,7 @@ class TerrascriptClient:
3309
3381
 
3310
3382
  self.add_resources(account, tf_resources)
3311
3383
 
3312
- def populate_tf_resource_s3_cloudfront(self, spec):
3384
+ def populate_tf_resource_s3_cloudfront(self, spec: ExternalResourceSpec) -> None:
3313
3385
  account = spec.provisioner_name
3314
3386
  identifier = spec.identifier
3315
3387
  common_values = self.init_values(spec)
@@ -3317,17 +3389,15 @@ class TerrascriptClient:
3317
3389
 
3318
3390
  bucket_tf_resource = self.populate_tf_resource_s3(spec)
3319
3391
 
3320
- tf_resources = []
3392
+ tf_resources: list[TFResource] = []
3321
3393
 
3322
3394
  # cloudfront origin access identity
3323
- values = {}
3324
- values["comment"] = f"{identifier}-cf-identity"
3395
+ values = {"comment": f"{identifier}-cf-identity"}
3325
3396
  cf_oai_tf_resource = aws_cloudfront_origin_access_identity(identifier, **values)
3326
3397
  tf_resources.append(cf_oai_tf_resource)
3327
3398
 
3328
3399
  # bucket policy for cloudfront
3329
- values = {}
3330
- values["bucket"] = identifier
3400
+ values_policy: dict[str, Any] = {"bucket": identifier}
3331
3401
  policy = {
3332
3402
  "Version": "2012-10-17",
3333
3403
  "Statement": [
@@ -3345,26 +3415,27 @@ class TerrascriptClient:
3345
3415
  }
3346
3416
  ],
3347
3417
  }
3348
- values["policy"] = json.dumps(policy, sort_keys=True)
3349
- values["depends_on"] = self.get_dependencies([bucket_tf_resource])
3418
+ values_policy["policy"] = json.dumps(policy, sort_keys=True)
3419
+ values_policy["depends_on"] = self.get_dependencies([bucket_tf_resource])
3350
3420
  region = common_values.get("region") or self.default_regions.get(account)
3421
+ assert region # make mypy happy
3351
3422
  if self._multiregion_account(account):
3352
- values["provider"] = "aws." + region
3353
- bucket_policy_tf_resource = aws_s3_bucket_policy(identifier, **values)
3423
+ values_policy["provider"] = "aws." + region
3424
+ bucket_policy_tf_resource = aws_s3_bucket_policy(identifier, **values_policy)
3354
3425
  tf_resources.append(bucket_policy_tf_resource)
3355
3426
 
3356
- values = common_values.get("distribution_config", {})
3427
+ distribution_config = common_values.get("distribution_config", {})
3357
3428
  # aws_s3_bucket_acl
3358
- if "logging_config" in values:
3429
+ if "logging_config" in distribution_config:
3359
3430
  # we could set this at a global level with a standard name like "cloudfront"
3360
3431
  # but we need all aws accounts upgraded to aws provider >3.60 first
3361
3432
  tf_resources.append(
3362
3433
  aws_cloudfront_log_delivery_canonical_user_id(identifier)
3363
3434
  )
3364
3435
 
3365
- logging_config_bucket = values["logging_config"]
3436
+ logging_config_bucket = distribution_config["logging_config"]
3366
3437
  acl_values = {}
3367
- access_control_policy = {
3438
+ access_control_policy: dict[str, Any] = {
3368
3439
  "owner": {
3369
3440
  "id": "${data.aws_canonical_user_id.current.id}",
3370
3441
  },
@@ -3388,7 +3459,7 @@ class TerrascriptClient:
3388
3459
  }
3389
3460
  external_account_id = logging_config_bucket.pop("external_account_id", None)
3390
3461
  if external_account_id:
3391
- external_account_policy = {
3462
+ external_account_policy: dict[str, Any] = {
3392
3463
  "grantee": {
3393
3464
  "id": external_account_id,
3394
3465
  "type": "CanonicalUser",
@@ -3403,13 +3474,15 @@ class TerrascriptClient:
3403
3474
  tf_resources.append(aws_s3_bucket_acl_resource)
3404
3475
 
3405
3476
  # cloud front distribution
3406
- values["tags"] = common_values["tags"]
3407
- values.setdefault("default_cache_behavior", {}).setdefault(
3477
+ distribution_config["tags"] = common_values["tags"]
3478
+ distribution_config.setdefault("default_cache_behavior", {}).setdefault(
3408
3479
  "target_origin_id", "default"
3409
3480
  )
3410
3481
  origin = {
3411
3482
  "domain_name": "${" + bucket_tf_resource.bucket_domain_name + "}",
3412
- "origin_id": values["default_cache_behavior"]["target_origin_id"],
3483
+ "origin_id": distribution_config["default_cache_behavior"][
3484
+ "target_origin_id"
3485
+ ],
3413
3486
  "s3_origin_config": {
3414
3487
  "origin_access_identity": "origin-access-identity/cloudfront/"
3415
3488
  + "${"
@@ -3417,8 +3490,10 @@ class TerrascriptClient:
3417
3490
  + "}"
3418
3491
  },
3419
3492
  }
3420
- values["origin"] = [origin]
3421
- cf_distribution_tf_resource = aws_cloudfront_distribution(identifier, **values)
3493
+ distribution_config["origin"] = [origin]
3494
+ cf_distribution_tf_resource = aws_cloudfront_distribution(
3495
+ identifier, **distribution_config
3496
+ )
3422
3497
  tf_resources.append(cf_distribution_tf_resource)
3423
3498
 
3424
3499
  # outputs
@@ -3443,7 +3518,7 @@ class TerrascriptClient:
3443
3518
 
3444
3519
  self.add_resources(account, tf_resources)
3445
3520
 
3446
- def populate_tf_resource_s3_sqs(self, spec):
3521
+ def populate_tf_resource_s3_sqs(self, spec: ExternalResourceSpec) -> None:
3447
3522
  account = spec.provisioner_name
3448
3523
  identifier = spec.identifier
3449
3524
  common_values = self.init_values(spec)
@@ -3453,12 +3528,13 @@ class TerrascriptClient:
3453
3528
  bucket_tf_resource = self.populate_tf_resource_s3(spec)
3454
3529
 
3455
3530
  region = common_values.get("region") or self.default_regions.get(account)
3531
+ assert region # make mypy happy
3456
3532
  provider = ""
3457
3533
  if self._multiregion_account(account):
3458
3534
  provider = "aws." + region
3459
- tf_resources = []
3535
+ tf_resources: list[TFResource] = []
3460
3536
  sqs_identifier = f"{identifier}-sqs"
3461
- sqs_values = {"name": sqs_identifier}
3537
+ sqs_values: dict[str, Any] = {"name": sqs_identifier}
3462
3538
 
3463
3539
  sqs_values["visibility_timeout_seconds"] = int(
3464
3540
  common_values.get("visibility_timeout_seconds", 30)
@@ -3491,15 +3567,15 @@ class TerrascriptClient:
3491
3567
  if kms_encryption:
3492
3568
  kms_identifier = f"{identifier}-kms"
3493
3569
  kms_values = {
3494
- "description": "app-interface created KMS key for" + sqs_identifier
3570
+ "description": "app-interface created KMS key for" + sqs_identifier,
3571
+ "key_usage": str(
3572
+ common_values.get("key_usage", "ENCRYPT_DECRYPT")
3573
+ ).upper(),
3574
+ "customer_master_key_spec": str(
3575
+ common_values.get("customer_master_key_spec", "SYMMETRIC_DEFAULT")
3576
+ ).upper(),
3577
+ "is_enabled": common_values.get("is_enabled", True),
3495
3578
  }
3496
- kms_values["key_usage"] = str(
3497
- common_values.get("key_usage", "ENCRYPT_DECRYPT")
3498
- ).upper()
3499
- kms_values["customer_master_key_spec"] = str(
3500
- common_values.get("customer_master_key_spec", "SYMMETRIC_DEFAULT")
3501
- ).upper()
3502
- kms_values["is_enabled"] = common_values.get("is_enabled", True)
3503
3579
 
3504
3580
  kms_policy = {
3505
3581
  "Version": "2012-10-17",
@@ -3575,16 +3651,16 @@ class TerrascriptClient:
3575
3651
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
3576
3652
 
3577
3653
  # iam user for queue
3578
- values = {}
3579
- values["name"] = sqs_identifier
3654
+ values: dict[str, Any] = {"name": sqs_identifier}
3580
3655
  user_tf_resource = aws_iam_user(sqs_identifier, **values)
3581
3656
  tf_resources.append(user_tf_resource)
3582
3657
 
3583
3658
  # iam access key for user
3584
- values = {}
3585
- values["user"] = sqs_identifier
3586
- values["depends_on"] = self.get_dependencies([user_tf_resource])
3587
- access_key_tf_resource = aws_iam_access_key(sqs_identifier, **values)
3659
+ values_key: dict[str, Any] = {
3660
+ "user": sqs_identifier,
3661
+ "depends_on": self.get_dependencies([user_tf_resource]),
3662
+ }
3663
+ access_key_tf_resource = aws_iam_access_key(sqs_identifier, **values_key)
3588
3664
  tf_resources.append(access_key_tf_resource)
3589
3665
  # outputs
3590
3666
  # sqs_aws_access_key_id
@@ -3597,9 +3673,8 @@ class TerrascriptClient:
3597
3673
  tf_resources.append(Output(output_name, value=output_value, sensitive=True))
3598
3674
 
3599
3675
  # iam policy for queue
3600
- values = {}
3601
- values["name"] = sqs_identifier
3602
- policy = {
3676
+ values_policy: dict[str, Any] = {"name": sqs_identifier}
3677
+ policy: dict[str, Any] = {
3603
3678
  "Version": "2012-10-17",
3604
3679
  "Statement": [
3605
3680
  {
@@ -3620,20 +3695,21 @@ class TerrascriptClient:
3620
3695
  "Resource": [sqs_values["kms_master_key_id"]],
3621
3696
  }
3622
3697
  policy["Statement"].append(kms_statement)
3623
- values["policy"] = json.dumps(policy, sort_keys=True)
3624
- policy_tf_resource = aws_iam_policy(sqs_identifier, **values)
3698
+ values_policy["policy"] = json.dumps(policy, sort_keys=True)
3699
+ policy_tf_resource = aws_iam_policy(sqs_identifier, **values_policy)
3625
3700
  tf_resources.append(policy_tf_resource)
3626
3701
 
3627
3702
  # iam user policy attachment
3628
- values = {}
3629
- values["user"] = sqs_identifier
3630
- values["policy_arn"] = "${" + policy_tf_resource.arn + "}"
3631
- values["depends_on"] = self.get_dependencies([
3632
- user_tf_resource,
3633
- policy_tf_resource,
3634
- ])
3703
+ values_user_policy: dict[str, Any] = {
3704
+ "user": sqs_identifier,
3705
+ "policy_arn": "${" + policy_tf_resource.arn + "}",
3706
+ "depends_on": self.get_dependencies([
3707
+ user_tf_resource,
3708
+ policy_tf_resource,
3709
+ ]),
3710
+ }
3635
3711
  user_policy_attachment_tf_resource = aws_iam_user_policy_attachment(
3636
- sqs_identifier, **values
3712
+ sqs_identifier, **values_user_policy
3637
3713
  )
3638
3714
  tf_resources.append(user_policy_attachment_tf_resource)
3639
3715
 
@@ -3644,13 +3720,13 @@ class TerrascriptClient:
3644
3720
 
3645
3721
  self.add_resources(account, tf_resources)
3646
3722
 
3647
- def populate_tf_resource_cloudwatch(self, spec):
3723
+ def populate_tf_resource_cloudwatch(self, spec: ExternalResourceSpec) -> None:
3648
3724
  account = spec.provisioner_name
3649
3725
  identifier = spec.identifier
3650
3726
  common_values = self.init_values(spec)
3651
3727
  output_prefix = spec.output_prefix
3652
3728
 
3653
- tf_resources = []
3729
+ tf_resources: list[TFResource] = []
3654
3730
  self.init_common_outputs(tf_resources, spec)
3655
3731
 
3656
3732
  # ecr repository
@@ -3666,6 +3742,7 @@ class TerrascriptClient:
3666
3742
  }
3667
3743
 
3668
3744
  region = common_values.get("region") or self.default_regions.get(account)
3745
+ assert region # make mypy happy
3669
3746
  provider = ""
3670
3747
  if self._multiregion_account(account):
3671
3748
  provider = "aws." + region
@@ -3741,29 +3818,26 @@ class TerrascriptClient:
3741
3818
  "filename": zip_file,
3742
3819
  "source_code_hash": '${filebase64sha256("' + zip_file + '")}',
3743
3820
  "role": "${" + role_tf_resource.arn + "}",
3744
- }
3745
-
3746
- lambda_values["function_name"] = lambda_identifier
3747
- lambda_values["runtime"] = common_values.get("runtime", "nodejs18.x")
3748
- lambda_values["timeout"] = common_values.get("timeout", 30)
3749
- lambda_values["handler"] = common_values.get("handler", "index.handler")
3750
- lambda_values["memory_size"] = common_values.get("memory_size", 128)
3751
-
3752
- lambda_values["vpc_config"] = {
3753
- "subnet_ids": "${data.aws_elasticsearch_domain."
3754
- + es_identifier
3755
- + ".vpc_options.0.subnet_ids}",
3756
- "security_group_ids": "${data.aws_elasticsearch_domain."
3757
- + es_identifier
3758
- + ".vpc_options.0.security_group_ids}",
3759
- }
3760
-
3761
- lambda_values["environment"] = {
3762
- "variables": {
3763
- "es_endpoint": "${data.aws_elasticsearch_domain."
3821
+ "function_name": lambda_identifier,
3822
+ "runtime": common_values.get("runtime", "nodejs18.x"),
3823
+ "timeout": common_values.get("timeout", 30),
3824
+ "handler": common_values.get("handler", "index.handler"),
3825
+ "memory_size": common_values.get("memory_size", 128),
3826
+ "vpc_config": {
3827
+ "subnet_ids": "${data.aws_elasticsearch_domain."
3764
3828
  + es_identifier
3765
- + ".endpoint}"
3766
- }
3829
+ + ".vpc_options.0.subnet_ids}",
3830
+ "security_group_ids": "${data.aws_elasticsearch_domain."
3831
+ + es_identifier
3832
+ + ".vpc_options.0.security_group_ids}",
3833
+ },
3834
+ "environment": {
3835
+ "variables": {
3836
+ "es_endpoint": "${data.aws_elasticsearch_domain."
3837
+ + es_identifier
3838
+ + ".endpoint}"
3839
+ }
3840
+ },
3767
3841
  }
3768
3842
 
3769
3843
  if provider:
@@ -3869,13 +3943,13 @@ class TerrascriptClient:
3869
3943
 
3870
3944
  self.add_resources(account, tf_resources)
3871
3945
 
3872
- def populate_tf_resource_kms(self, spec):
3946
+ def populate_tf_resource_kms(self, spec: ExternalResourceSpec) -> None:
3873
3947
  account = spec.provisioner_name
3874
3948
  identifier = spec.identifier
3875
3949
  values = self.init_values(spec)
3876
3950
  output_prefix = spec.output_prefix
3877
3951
 
3878
- tf_resources = []
3952
+ tf_resources: list[TFResource] = []
3879
3953
  self.init_common_outputs(tf_resources, spec)
3880
3954
  values.pop("identifier", None)
3881
3955
 
@@ -3892,6 +3966,7 @@ class TerrascriptClient:
3892
3966
  if key in values:
3893
3967
  values[key] = values[key].upper()
3894
3968
  region = values.pop("region", None) or self.default_regions.get(account)
3969
+ assert region # make mypy happy
3895
3970
  if self._multiregion_account(account):
3896
3971
  values["provider"] = "aws." + region
3897
3972
 
@@ -3903,9 +3978,10 @@ class TerrascriptClient:
3903
3978
  output_value = "${" + tf_resource.key_id + "}"
3904
3979
  tf_resources.append(Output(output_name, value=output_value))
3905
3980
 
3906
- alias_values = {}
3907
- alias_values["name"] = "alias/" + identifier
3908
- alias_values["target_key_id"] = "${aws_kms_key." + identifier + ".key_id}"
3981
+ alias_values = {
3982
+ "name": "alias/" + identifier,
3983
+ "target_key_id": "${aws_kms_key." + identifier + ".key_id}",
3984
+ }
3909
3985
  if self._multiregion_account(account):
3910
3986
  alias_values["provider"] = "aws." + region
3911
3987
  tf_resource = aws_kms_alias(identifier, **alias_values)
@@ -3913,28 +3989,30 @@ class TerrascriptClient:
3913
3989
 
3914
3990
  self.add_resources(account, tf_resources)
3915
3991
 
3916
- def populate_tf_resource_kinesis(self, spec):
3992
+ def populate_tf_resource_kinesis(self, spec: ExternalResourceSpec) -> None:
3917
3993
  account = spec.provisioner_name
3918
3994
  identifier = spec.identifier
3919
3995
  common_values = self.init_values(spec)
3920
3996
  output_prefix = spec.output_prefix
3921
3997
 
3922
- tf_resources = []
3998
+ tf_resources: list[TFResource] = []
3923
3999
  self.init_common_outputs(tf_resources, spec)
3924
4000
 
3925
- tags = common_values["tags"]
3926
- kinesis_values = {
4001
+ tags: dict[str, str] = common_values["tags"]
4002
+ kinesis_values: dict[str, Any] = {
3927
4003
  "name": identifier,
3928
4004
  "tags": tags,
4005
+ "shard_count": common_values.get("shard_count"),
4006
+ "retention_period": common_values.get("retention_period", 24),
4007
+ "encryption_type": common_values.get("encryption_type", None),
3929
4008
  }
3930
- kinesis_values["shard_count"] = common_values.get("shard_count")
3931
- kinesis_values["retention_period"] = common_values.get("retention_period", 24)
3932
- kinesis_values["encryption_type"] = common_values.get("encryption_type", None)
4009
+
3933
4010
  if kinesis_values["encryption_type"] == "KMS":
3934
4011
  kinesis_values["kms_key_id"] = common_values.get("kms_key_id")
3935
4012
 
3936
4013
  # get region and set provider if required
3937
4014
  region = common_values.get("region") or self.default_regions.get(account)
4015
+ assert region # make mypy happy
3938
4016
  provider = ""
3939
4017
  if self._multiregion_account(account):
3940
4018
  provider = "aws." + region
@@ -4054,34 +4132,31 @@ class TerrascriptClient:
4054
4132
  "source_code_hash": '${filebase64sha256("' + zip_file + '")}',
4055
4133
  "role": "${" + role_tf_resource.arn + "}",
4056
4134
  "tags": tags,
4057
- }
4058
-
4059
- lambda_values["function_name"] = lambda_identifier
4060
- lambda_values["runtime"] = common_values.get("runtime", "python3.9")
4061
- lambda_values["timeout"] = common_values.get("timeout", 30)
4062
- lambda_values["handler"] = common_values.get(
4063
- "handler", "lambda_function.handler"
4064
- )
4065
- lambda_values["memory_size"] = common_values.get("memory_size", 128)
4066
-
4067
- lambda_values["vpc_config"] = {
4068
- "subnet_ids": "${data.aws_elasticsearch_domain."
4069
- + es_identifier
4070
- + ".vpc_options.0.subnet_ids}",
4071
- "security_group_ids": "${data.aws_elasticsearch_domain."
4072
- + es_identifier
4073
- + ".vpc_options.0.security_group_ids}",
4074
- }
4075
-
4076
- index_prefix = common_values.get("index_prefix", f"{identifier}-")
4077
- lambda_values["environment"] = {
4078
- "variables": {
4079
- "es_endpoint": "${data.aws_elasticsearch_domain."
4135
+ "function_name": lambda_identifier,
4136
+ "runtime": common_values.get("runtime", "python3.9"),
4137
+ "timeout": common_values.get("timeout", 30),
4138
+ "handler": common_values.get("handler", "lambda_function.handler"),
4139
+ "memory_size": common_values.get("memory_size", 128),
4140
+ "vpc_config": {
4141
+ "subnet_ids": "${data.aws_elasticsearch_domain."
4080
4142
  + es_identifier
4081
- + ".endpoint}",
4082
- "index_prefix": index_prefix,
4083
- }
4143
+ + ".vpc_options.0.subnet_ids}",
4144
+ "security_group_ids": "${data.aws_elasticsearch_domain."
4145
+ + es_identifier
4146
+ + ".vpc_options.0.security_group_ids}",
4147
+ },
4148
+ "environment": {
4149
+ "variables": {
4150
+ "es_endpoint": "${data.aws_elasticsearch_domain."
4151
+ + es_identifier
4152
+ + ".endpoint}",
4153
+ "index_prefix": common_values.get(
4154
+ "index_prefix", f"{identifier}-"
4155
+ ),
4156
+ }
4157
+ },
4084
4158
  }
4159
+
4085
4160
  secret_name = es_resource.get_secret_field("secret_name")
4086
4161
  if secret_name:
4087
4162
  lambda_values["environment"]["variables"]["secret_name"] = secret_name
@@ -4160,7 +4235,9 @@ class TerrascriptClient:
4160
4235
  self.add_resources(account, tf_resources)
4161
4236
 
4162
4237
  @staticmethod
4163
- def _get_retention_in_days(values, account, identifier):
4238
+ def _get_retention_in_days(
4239
+ values: Mapping[str, Any], account: str, identifier: str
4240
+ ) -> int:
4164
4241
  default_retention_in_days = 14
4165
4242
  allowed_retention_in_days = [
4166
4243
  1,
@@ -4194,17 +4271,21 @@ class TerrascriptClient:
4194
4271
  return retention_in_days
4195
4272
 
4196
4273
  def get_tf_iam_service_user(
4197
- self, dep_tf_resource, identifier, policy, tags, output_prefix
4198
- ):
4274
+ self,
4275
+ dep_tf_resource: TFResource | None,
4276
+ identifier: str,
4277
+ policy: Mapping[str, Any],
4278
+ tags: Mapping[str, str],
4279
+ output_prefix: str,
4280
+ ) -> list[TFResource]:
4199
4281
  # iam resources
4200
4282
  # Terraform resource reference:
4201
4283
  # https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
4202
- tf_resources = []
4284
+ tf_resources: list[TFResource] = []
4203
4285
 
4204
4286
  # iam user
4205
- values = {}
4206
- values["name"] = identifier
4207
- values["tags"] = tags
4287
+ values: dict[str, Any] = {"name": identifier, "tags": tags}
4288
+
4208
4289
  if dep_tf_resource:
4209
4290
  values["depends_on"] = self.get_dependencies([dep_tf_resource])
4210
4291
  user_tf_resource = aws_iam_user(identifier, **values)
@@ -4216,12 +4297,13 @@ class TerrascriptClient:
4216
4297
  )
4217
4298
 
4218
4299
  # iam user policy
4219
- values = {}
4220
- values["name"] = identifier
4221
- values["policy"] = json.dumps(policy, sort_keys=True)
4222
- values["depends_on"] = self.get_dependencies([user_tf_resource])
4300
+ values_policy: dict[str, Any] = {
4301
+ "name": identifier,
4302
+ "policy": json.dumps(policy, sort_keys=True),
4303
+ "depends_on": self.get_dependencies([user_tf_resource]),
4304
+ }
4223
4305
 
4224
- tf_aws_iam_policy = aws_iam_policy(identifier, **values)
4306
+ tf_aws_iam_policy = aws_iam_policy(identifier, **values_policy)
4225
4307
  tf_resources.append(tf_aws_iam_policy)
4226
4308
 
4227
4309
  tf_aws_iam_user_policy_attachment = aws_iam_user_policy_attachment(
@@ -4234,11 +4316,15 @@ class TerrascriptClient:
4234
4316
 
4235
4317
  return tf_resources
4236
4318
 
4237
- def get_tf_iam_access_key(self, user_tf_resource, identifier, output_prefix):
4238
- tf_resources = []
4239
- values = {}
4240
- values["user"] = identifier
4241
- values["depends_on"] = self.get_dependencies([user_tf_resource])
4319
+ def get_tf_iam_access_key(
4320
+ self, user_tf_resource: aws_iam_user, identifier: str, output_prefix: str
4321
+ ) -> list[TFResource]:
4322
+ tf_resources: list[TFResource] = []
4323
+ values: dict[str, Any] = {
4324
+ "user": identifier,
4325
+ "depends_on": self.get_dependencies([user_tf_resource]),
4326
+ }
4327
+
4242
4328
  tf_resource = aws_iam_access_key(identifier, **values)
4243
4329
  tf_resources.append(tf_resource)
4244
4330
  # outputs
@@ -4253,11 +4339,11 @@ class TerrascriptClient:
4253
4339
 
4254
4340
  return tf_resources
4255
4341
 
4256
- def add_resources(self, account, tf_resources):
4342
+ def add_resources(self, account: str, tf_resources: Iterable[TFResource]) -> None:
4257
4343
  for r in tf_resources:
4258
4344
  self.add_resource(account, r)
4259
4345
 
4260
- def add_resource(self, account, tf_resource):
4346
+ def add_resource(self, account: str, tf_resource: TFResource) -> None:
4261
4347
  if account not in self.locks:
4262
4348
  logging.debug(
4263
4349
  f"integration {self.integration} is disabled for account {account}. "
@@ -4267,7 +4353,7 @@ class TerrascriptClient:
4267
4353
  with self.locks[account]:
4268
4354
  self.tss[account].add(tf_resource)
4269
4355
 
4270
- def add_moved(self, account: str, moved: Moved):
4356
+ def add_moved(self, account: str, moved: Moved) -> None:
4271
4357
  if account not in self.locks:
4272
4358
  logging.debug(
4273
4359
  f"integration {self.integration} is disabled for account {account}. "
@@ -4336,7 +4422,9 @@ class TerrascriptClient:
4336
4422
  for name, ts in self.tss.items()
4337
4423
  }
4338
4424
 
4339
- def init_values(self, spec: ExternalResourceSpec, init_tags: bool = True) -> dict:
4425
+ def init_values(
4426
+ self, spec: ExternalResourceSpec, init_tags: bool = True
4427
+ ) -> dict[str, Any]:
4340
4428
  """
4341
4429
  Initialize the values of the terraform resource and merge the defaults and
4342
4430
  overrides.
@@ -4389,7 +4477,7 @@ class TerrascriptClient:
4389
4477
  return values
4390
4478
 
4391
4479
  @staticmethod
4392
- def aggregate_values(values):
4480
+ def aggregate_values(values: dict[str, Any]) -> None:
4393
4481
  split_char = "."
4394
4482
  copy = values.copy()
4395
4483
  for k, v in copy.items():
@@ -4403,18 +4491,17 @@ class TerrascriptClient:
4403
4491
  values.pop(k, None)
4404
4492
 
4405
4493
  @staticmethod
4406
- def override_values(values, overrides):
4494
+ def override_values(values: dict[str, Any], overrides: str | None) -> None:
4407
4495
  if overrides is None:
4408
4496
  return
4409
4497
  data = json.loads(overrides)
4410
- for k, v in data.items():
4411
- values[k] = v
4498
+ values.update(data)
4412
4499
 
4413
4500
  def init_common_outputs(
4414
4501
  self,
4415
- tf_resources: list[Resource],
4502
+ tf_resources: list[TFResource],
4416
4503
  spec: ExternalResourceSpec,
4417
- ):
4504
+ ) -> None:
4418
4505
  output_format = "{}__{}_{}"
4419
4506
  # cluster
4420
4507
  output_name = output_format.format(
@@ -4449,11 +4536,11 @@ class TerrascriptClient:
4449
4536
  output_value = base64.b64encode(anno_json).decode()
4450
4537
  tf_resources.append(Output(output_name, value=output_value))
4451
4538
 
4452
- def prefetch_resources(self, schema) -> dict[str, dict[str, str]]:
4539
+ def prefetch_resources(self, schema: str) -> dict[str, dict[str, str]]:
4453
4540
  gqlapi = gql.get_api()
4454
4541
  return {r["path"]: r for r in gqlapi.get_resources_by_schema(schema)}
4455
4542
 
4456
- def get_raw_values(self, path) -> dict[str, str]:
4543
+ def get_raw_values(self, path: str) -> dict[str, str]:
4457
4544
  if path in self._resource_cache:
4458
4545
  return self._resource_cache[path]
4459
4546
 
@@ -4482,7 +4569,7 @@ class TerrascriptClient:
4482
4569
  ]
4483
4570
 
4484
4571
  @staticmethod
4485
- def get_elasticsearch_service_role_tf_resource():
4572
+ def get_elasticsearch_service_role_tf_resource() -> aws_iam_service_linked_role:
4486
4573
  """Service role for ElasticSearch."""
4487
4574
  service_role = {
4488
4575
  "aws_service_name": "es.amazonaws.com",
@@ -4490,7 +4577,7 @@ class TerrascriptClient:
4490
4577
  return aws_iam_service_linked_role("elasticsearch", **service_role)
4491
4578
 
4492
4579
  @staticmethod
4493
- def is_elasticsearch_domain_name_valid(name):
4580
+ def is_elasticsearch_domain_name_valid(name: str) -> bool:
4494
4581
  """Handle for Error creating Elasticsearch:
4495
4582
  InvalidParameterValue: Elasticsearch domain name must start with a
4496
4583
  lowercase letter and must be between 3 and 28 characters. Valid
@@ -4498,7 +4585,7 @@ class TerrascriptClient:
4498
4585
  if len(name) < 3 or len(name) > 28:
4499
4586
  return False
4500
4587
  pattern = r"^[a-z][a-z0-9-]+$"
4501
- return re.search(pattern, name)
4588
+ return re.search(pattern, name) is not None
4502
4589
 
4503
4590
  @staticmethod
4504
4591
  def elasticsearch_log_group_identifier(
@@ -4600,7 +4687,7 @@ class TerrascriptClient:
4600
4687
  resource: Mapping[str, Any],
4601
4688
  values: Mapping[str, Any],
4602
4689
  output_prefix: str,
4603
- ) -> tuple[list[dict[str, Any]], list[dict[str, object]]]:
4690
+ ) -> tuple[list[TFResource], list[dict[str, object]]]:
4604
4691
  """
4605
4692
  Generate cloud_watch_log_group terraform_resources
4606
4693
  for the given resource. Further, generate
@@ -4608,7 +4695,7 @@ class TerrascriptClient:
4608
4695
  by the consumer.
4609
4696
  """
4610
4697
  es_log_group_retention_days = 90
4611
- tf_resources = []
4698
+ tf_resources: list[TFResource] = []
4612
4699
  publishing_options = []
4613
4700
 
4614
4701
  # res.get('', []) won't work, as publish_log_types is
@@ -4711,13 +4798,13 @@ class TerrascriptClient:
4711
4798
 
4712
4799
  return advanced_security_options
4713
4800
 
4714
- def populate_tf_resource_elasticsearch(self, spec):
4801
+ def populate_tf_resource_elasticsearch(self, spec: ExternalResourceSpec) -> None:
4715
4802
  account = spec.provisioner_name
4716
4803
  identifier = spec.identifier
4717
4804
  values = self.init_values(spec)
4718
4805
  output_prefix = spec.output_prefix
4719
4806
 
4720
- tf_resources = []
4807
+ tf_resources: list[TFResource] = []
4721
4808
  self.init_common_outputs(tf_resources, spec)
4722
4809
 
4723
4810
  if not self.is_elasticsearch_domain_name_valid(values["identifier"]):
@@ -4730,10 +4817,11 @@ class TerrascriptClient:
4730
4817
  )
4731
4818
 
4732
4819
  tags = values["tags"]
4733
- es_values = {}
4734
- es_values["domain_name"] = identifier
4735
- es_values["tags"] = tags
4736
- es_values["elasticsearch_version"] = values.get("elasticsearch_version")
4820
+ es_values: dict[str, Any] = {
4821
+ "domain_name": identifier,
4822
+ "tags": tags,
4823
+ "elasticsearch_version": values.get("elasticsearch_version"),
4824
+ }
4737
4825
 
4738
4826
  (
4739
4827
  log_group_resources,
@@ -4919,6 +5007,7 @@ class TerrascriptClient:
4919
5007
  es_values["access_policies"] = json.dumps(access_policies, sort_keys=True)
4920
5008
 
4921
5009
  region = values.get("region") or self.default_regions.get(account)
5010
+ assert region # make mypy happy
4922
5011
  provider = ""
4923
5012
  if self._multiregion_account(account):
4924
5013
  provider = "aws." + region
@@ -5057,8 +5146,8 @@ class TerrascriptClient:
5057
5146
 
5058
5147
  # TODO: @fishi0x01 remove this function after migration APPSRE-3409
5059
5148
  def _build_es_advanced_security_options_deprecated(
5060
- self, advanced_security_options: MutableMapping[str, Any]
5061
- ) -> MutableMapping[str, Any]:
5149
+ self, advanced_security_options: dict[str, Any]
5150
+ ) -> dict[str, Any]:
5062
5151
  master_user_options = advanced_security_options.pop("master_user_options", {})
5063
5152
 
5064
5153
  if master_user_options:
@@ -5079,13 +5168,13 @@ class TerrascriptClient:
5079
5168
 
5080
5169
  return advanced_security_options
5081
5170
 
5082
- def populate_tf_resource_acm(self, spec):
5171
+ def populate_tf_resource_acm(self, spec: ExternalResourceSpec) -> None:
5083
5172
  account = spec.provisioner_name
5084
5173
  identifier = spec.identifier
5085
5174
  common_values = self.init_values(spec)
5086
5175
  output_prefix = spec.output_prefix
5087
5176
 
5088
- tf_resources = []
5177
+ tf_resources: list[TFResource] = []
5089
5178
  self.init_common_outputs(tf_resources, spec)
5090
5179
 
5091
5180
  values = {}
@@ -5124,6 +5213,7 @@ class TerrascriptClient:
5124
5213
  values["subject_alternative_names"] = alt_names
5125
5214
 
5126
5215
  region = common_values.get("region") or self.default_regions.get(account)
5216
+ assert region # make mypy happy
5127
5217
  if self._multiregion_account(account):
5128
5218
  values["provider"] = "aws." + region
5129
5219
 
@@ -5165,13 +5255,15 @@ class TerrascriptClient:
5165
5255
 
5166
5256
  self.add_resources(account, tf_resources)
5167
5257
 
5168
- def populate_tf_resource_s3_cloudfront_public_key(self, spec):
5258
+ def populate_tf_resource_s3_cloudfront_public_key(
5259
+ self, spec: ExternalResourceSpec
5260
+ ) -> None:
5169
5261
  account = spec.provisioner_name
5170
5262
  identifier = spec.identifier
5171
5263
  common_values = self.init_values(spec)
5172
5264
  output_prefix = spec.output_prefix
5173
5265
 
5174
- tf_resources = []
5266
+ tf_resources: list[TFResource] = []
5175
5267
  self.init_common_outputs(tf_resources, spec)
5176
5268
 
5177
5269
  values = {"name": identifier, "comment": "managed by app-interface"}
@@ -5213,8 +5305,13 @@ class TerrascriptClient:
5213
5305
  self.add_resources(account, tf_resources)
5214
5306
 
5215
5307
  def _get_alb_target_ips_by_openshift_service(
5216
- self, identifier, openshift_service, account_name, namespace_info, ocm_map
5217
- ):
5308
+ self,
5309
+ identifier: str,
5310
+ openshift_service: str,
5311
+ account_name: str,
5312
+ namespace_info: Mapping[str, Any],
5313
+ ocm_map: OCMMap,
5314
+ ) -> set[str]:
5218
5315
  account = self.accounts[account_name]
5219
5316
  cluster = namespace_info["cluster"]
5220
5317
  ocm = ocm_map.get(cluster["name"])
@@ -5240,7 +5337,9 @@ class TerrascriptClient:
5240
5337
  return ips
5241
5338
 
5242
5339
  @staticmethod
5243
- def _get_alb_rule_condition_value(condition):
5340
+ def _get_alb_rule_condition_value(
5341
+ condition: Mapping[str, Any],
5342
+ ) -> dict[str, dict[str, str]]:
5244
5343
  condition_type = condition["type"]
5245
5344
  condition_type_key = SUPPORTED_ALB_LISTENER_RULE_CONDITION_TYPE_MAPPING.get(
5246
5345
  condition_type
@@ -5250,7 +5349,7 @@ class TerrascriptClient:
5250
5349
  return {condition_type_key: {"values": condition[condition_type_key]}}
5251
5350
 
5252
5351
  @staticmethod
5253
- def _get_principal_for_s3_bucket_policy(region: str) -> Mapping[str, str]:
5352
+ def _get_principal_for_s3_bucket_policy(region: str) -> dict[str, str]:
5254
5353
  if region in AWS_ELB_ACCOUNT_IDS:
5255
5354
  return {"AWS": f"arn:aws:iam::{AWS_ELB_ACCOUNT_IDS[region]}:root"}
5256
5355
  if region in AWS_US_GOV_ELB_ACCOUNT_IDS:
@@ -5259,16 +5358,18 @@ class TerrascriptClient:
5259
5358
  }
5260
5359
  return {"Service": "logdelivery.elasticloadbalancing.amazonaws.com"}
5261
5360
 
5262
- def populate_tf_resource_alb(self, spec, ocm_map=None):
5361
+ def populate_tf_resource_alb(
5362
+ self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
5363
+ ) -> None:
5263
5364
  account = spec.provisioner_name
5264
5365
  identifier = spec.identifier
5265
5366
  common_values = self.init_values(spec)
5266
5367
  output_prefix = spec.output_prefix
5267
- tf_resources = []
5368
+ tf_resources: list[TFResource] = []
5268
5369
  namespace_info = spec.namespace
5269
5370
  self.init_common_outputs(tf_resources, spec)
5270
5371
 
5271
- default_region = self.default_regions.get(account)
5372
+ default_region = self.default_regions[account]
5272
5373
  cluster_region = namespace_info["cluster"]["spec"]["region"]
5273
5374
 
5274
5375
  if self._multiregion_account(account):
@@ -5421,6 +5522,10 @@ class TerrascriptClient:
5421
5522
  t_protocol_version = t.get("protocol_version") or "HTTP1"
5422
5523
 
5423
5524
  if t_openshift_service:
5525
+ if ocm_map is None:
5526
+ raise ValueError(
5527
+ "ocm_map should be not none raising exception to make mypy happy"
5528
+ )
5424
5529
  target_ips = self._get_alb_target_ips_by_openshift_service(
5425
5530
  identifier, t_openshift_service, account, namespace_info, ocm_map
5426
5531
  )
@@ -5593,7 +5698,7 @@ class TerrascriptClient:
5593
5698
  for rule_num, rule in enumerate(resource["rules"]):
5594
5699
  # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#type
5595
5700
  action = rule["action"]
5596
- action_values = {}
5701
+ action_values: dict[str, Any] = {}
5597
5702
  action_type = action.get("type")
5598
5703
  if action_type == "forward":
5599
5704
  action_values = {
@@ -5679,18 +5784,19 @@ class TerrascriptClient:
5679
5784
 
5680
5785
  self.add_resources(account, tf_resources)
5681
5786
 
5682
- def populate_tf_resource_secrets_manager(self, spec):
5787
+ def populate_tf_resource_secrets_manager(self, spec: ExternalResourceSpec) -> None:
5683
5788
  account = spec.provisioner_name
5684
5789
  identifier = spec.identifier
5685
5790
  common_values = self.init_values(spec)
5686
5791
  output_prefix = spec.output_prefix
5687
5792
 
5688
- tf_resources = []
5793
+ tf_resources: list[TFResource] = []
5689
5794
  self.init_common_outputs(tf_resources, spec)
5690
5795
 
5691
5796
  values = {"name": identifier}
5692
5797
 
5693
5798
  region = common_values.get("region") or self.default_regions.get(account)
5799
+ assert region # make mypy happy
5694
5800
  if self._multiregion_account(account):
5695
5801
  values["provider"] = "aws." + region
5696
5802
 
@@ -5698,9 +5804,10 @@ class TerrascriptClient:
5698
5804
  tf_resources.append(aws_secret_resource)
5699
5805
 
5700
5806
  secret = common_values.get("secret")
5807
+ assert secret # make mypy happy
5701
5808
  secret_data = self.secret_reader.read_all(secret)
5702
5809
 
5703
- version_values = {
5810
+ version_values: dict[str, Any] = {
5704
5811
  "secret_id": "${" + aws_secret_resource.id + "}",
5705
5812
  "secret_string": json.dumps(secret_data, sort_keys=True),
5706
5813
  }
@@ -5781,7 +5888,7 @@ class TerrascriptClient:
5781
5888
  return True
5782
5889
  return False
5783
5890
 
5784
- def populate_tf_resource_asg(self, spec) -> None:
5891
+ def populate_tf_resource_asg(self, spec: ExternalResourceSpec) -> None:
5785
5892
  account = spec.provisioner_name
5786
5893
  identifier = spec.identifier
5787
5894
  common_values = self.init_values(spec)
@@ -5868,7 +5975,7 @@ class TerrascriptClient:
5868
5975
  template_resource = aws_launch_template(identifier, **template_values)
5869
5976
  tf_resources.append(template_resource)
5870
5977
 
5871
- asg_value = {
5978
+ asg_value: dict[str, Any] = {
5872
5979
  "name": identifier,
5873
5980
  "max_size": common_values.get("max_size"),
5874
5981
  "min_size": common_values.get("min_size"),
@@ -5924,12 +6031,12 @@ class TerrascriptClient:
5924
6031
 
5925
6032
  self.add_resources(account, tf_resources)
5926
6033
 
5927
- def populate_tf_resource_route53_zone(self, spec):
6034
+ def populate_tf_resource_route53_zone(self, spec: ExternalResourceSpec) -> None:
5928
6035
  account = spec.provisioner_name
5929
6036
  identifier = spec.identifier
5930
6037
  common_values = self.init_values(spec)
5931
6038
  output_prefix = spec.output_prefix
5932
- tf_resources = []
6039
+ tf_resources: list[TFResource] = []
5933
6040
  self.init_common_outputs(tf_resources, spec)
5934
6041
 
5935
6042
  # https://www.terraform.io/docs/providers/aws/r/route53_zone.html
@@ -5973,16 +6080,20 @@ class TerrascriptClient:
5973
6080
 
5974
6081
  self.add_resources(account, tf_resources)
5975
6082
 
5976
- def populate_tf_resource_rosa_authenticator(self, spec):
6083
+ def populate_tf_resource_rosa_authenticator(
6084
+ self, spec: ExternalResourceSpec
6085
+ ) -> None:
5977
6086
  account = spec.provisioner_name
5978
6087
  identifier = spec.identifier
5979
6088
  common_values = self.init_values(spec)
5980
- tf_resources = []
6089
+ tf_resources: list[TFResource] = []
5981
6090
  self.init_common_outputs(tf_resources, spec)
5982
6091
 
5983
6092
  # Prepare consts
5984
6093
  region = common_values.get("region") or self.default_regions.get(account)
6094
+ assert region # make mypy happy
5985
6095
  bucket_name = common_values.get("cognito_callback_bucket_name")
6096
+ assert bucket_name # make mypy happy
5986
6097
  bucket_url = f"https://{bucket_name}.s3.{region}.amazonaws.com"
5987
6098
  lambda_managed_policy_arn = (
5988
6099
  "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
@@ -5992,6 +6103,7 @@ class TerrascriptClient:
5992
6103
  vpc_id = common_values.get("vpc_id")
5993
6104
  subnet_ids = common_values.get("subnet_ids")
5994
6105
  network_interface_ids = common_values.get("network_interface_ids")
6106
+ assert network_interface_ids is not None # make mypy happy
5995
6107
  certificate_arn = common_values.get("certificate_arn")
5996
6108
  domain_name = common_values.get("domain_name")
5997
6109
  openshift_ingress_load_balancer_arn = common_values.get(
@@ -6868,15 +6980,18 @@ class TerrascriptClient:
6868
6980
 
6869
6981
  self.add_resources(account, tf_resources)
6870
6982
 
6871
- def populate_tf_resource_rosa_authenticator_vpce(self, spec):
6983
+ def populate_tf_resource_rosa_authenticator_vpce(
6984
+ self, spec: ExternalResourceSpec
6985
+ ) -> None:
6872
6986
  account = spec.provisioner_name
6873
6987
  identifier = spec.identifier
6874
6988
  common_values = self.init_values(spec)
6875
- tf_resources = []
6989
+ tf_resources: list[TFResource] = []
6876
6990
  self.init_common_outputs(tf_resources, spec)
6877
6991
 
6878
6992
  vpc_id = common_values.get("vpc_id")
6879
6993
  subnet_ids = common_values.get("subnet_ids")
6994
+ assert subnet_ids is not None # make mypy happy
6880
6995
  vpce_security_group_rule_common_args = common_values.get(
6881
6996
  "vpce_security_group_rule_common_properties", None
6882
6997
  )
@@ -6935,11 +7050,11 @@ class TerrascriptClient:
6935
7050
 
6936
7051
  self.add_resources(account, tf_resources)
6937
7052
 
6938
- def populate_tf_resource_msk(self, spec):
7053
+ def populate_tf_resource_msk(self, spec: ExternalResourceSpec) -> None:
6939
7054
  account = spec.provisioner_name
6940
7055
  values = self.init_values(spec)
6941
7056
  output_prefix = spec.output_prefix
6942
- tf_resources = []
7057
+ tf_resources: list[TFResource] = []
6943
7058
  resource_id = spec.identifier
6944
7059
 
6945
7060
  del values["identifier"]