atlas-init 0.1.0__py3-none-any.whl → 0.1.4__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.
Files changed (74) hide show
  1. atlas_init/__init__.py +3 -3
  2. atlas_init/atlas_init.yaml +51 -34
  3. atlas_init/cli.py +76 -72
  4. atlas_init/cli_cfn/app.py +40 -117
  5. atlas_init/cli_cfn/{cfn.py → aws.py} +129 -14
  6. atlas_init/cli_cfn/cfn_parameter_finder.py +89 -6
  7. atlas_init/cli_cfn/example.py +203 -0
  8. atlas_init/cli_cfn/files.py +63 -0
  9. atlas_init/cli_helper/go.py +6 -3
  10. atlas_init/cli_helper/run.py +18 -2
  11. atlas_init/cli_helper/tf_runner.py +12 -21
  12. atlas_init/cli_root/__init__.py +0 -0
  13. atlas_init/cli_root/trigger.py +153 -0
  14. atlas_init/cli_tf/app.py +211 -4
  15. atlas_init/cli_tf/changelog.py +103 -0
  16. atlas_init/cli_tf/debug_logs.py +221 -0
  17. atlas_init/cli_tf/debug_logs_test_data.py +253 -0
  18. atlas_init/cli_tf/github_logs.py +229 -0
  19. atlas_init/cli_tf/go_test_run.py +194 -0
  20. atlas_init/cli_tf/go_test_run_format.py +31 -0
  21. atlas_init/cli_tf/go_test_summary.py +144 -0
  22. atlas_init/cli_tf/hcl/__init__.py +0 -0
  23. atlas_init/cli_tf/hcl/cli.py +161 -0
  24. atlas_init/cli_tf/hcl/cluster_mig.py +348 -0
  25. atlas_init/cli_tf/hcl/parser.py +140 -0
  26. atlas_init/cli_tf/schema.py +222 -18
  27. atlas_init/cli_tf/schema_go_parser.py +236 -0
  28. atlas_init/cli_tf/schema_table.py +150 -0
  29. atlas_init/cli_tf/schema_table_models.py +155 -0
  30. atlas_init/cli_tf/schema_v2.py +599 -0
  31. atlas_init/cli_tf/schema_v2_api_parsing.py +298 -0
  32. atlas_init/cli_tf/schema_v2_sdk.py +361 -0
  33. atlas_init/cli_tf/schema_v3.py +222 -0
  34. atlas_init/cli_tf/schema_v3_sdk.py +279 -0
  35. atlas_init/cli_tf/schema_v3_sdk_base.py +68 -0
  36. atlas_init/cli_tf/schema_v3_sdk_create.py +216 -0
  37. atlas_init/humps.py +253 -0
  38. atlas_init/repos/cfn.py +6 -1
  39. atlas_init/repos/path.py +3 -3
  40. atlas_init/settings/config.py +30 -11
  41. atlas_init/settings/env_vars.py +29 -3
  42. atlas_init/settings/path.py +12 -1
  43. atlas_init/settings/rich_utils.py +39 -2
  44. atlas_init/terraform.yaml +77 -1
  45. atlas_init/tf/.terraform.lock.hcl +125 -0
  46. atlas_init/tf/always.tf +11 -2
  47. atlas_init/tf/main.tf +3 -0
  48. atlas_init/tf/modules/aws_s3/provider.tf +1 -1
  49. atlas_init/tf/modules/aws_vars/aws_vars.tf +2 -0
  50. atlas_init/tf/modules/aws_vpc/provider.tf +4 -1
  51. atlas_init/tf/modules/cfn/cfn.tf +47 -33
  52. atlas_init/tf/modules/cfn/kms.tf +54 -0
  53. atlas_init/tf/modules/cfn/resource_actions.yaml +1 -0
  54. atlas_init/tf/modules/cfn/variables.tf +31 -0
  55. atlas_init/tf/modules/cloud_provider/cloud_provider.tf +1 -0
  56. atlas_init/tf/modules/cloud_provider/provider.tf +1 -1
  57. atlas_init/tf/modules/cluster/cluster.tf +34 -24
  58. atlas_init/tf/modules/cluster/provider.tf +1 -1
  59. atlas_init/tf/modules/federated_vars/federated_vars.tf +3 -0
  60. atlas_init/tf/modules/federated_vars/provider.tf +1 -1
  61. atlas_init/tf/modules/project_extra/project_extra.tf +15 -1
  62. atlas_init/tf/modules/stream_instance/stream_instance.tf +1 -1
  63. atlas_init/tf/modules/vpc_peering/vpc_peering.tf +1 -1
  64. atlas_init/tf/modules/vpc_privatelink/versions.tf +1 -1
  65. atlas_init/tf/outputs.tf +11 -3
  66. atlas_init/tf/providers.tf +2 -1
  67. atlas_init/tf/variables.tf +17 -0
  68. atlas_init/typer_app.py +76 -0
  69. {atlas_init-0.1.0.dist-info → atlas_init-0.1.4.dist-info}/METADATA +58 -21
  70. atlas_init-0.1.4.dist-info/RECORD +91 -0
  71. {atlas_init-0.1.0.dist-info → atlas_init-0.1.4.dist-info}/WHEEL +1 -1
  72. atlas_init-0.1.0.dist-info/RECORD +0 -61
  73. /atlas_init/tf/modules/aws_vpc/{aws-vpc.tf → aws_vpc.tf} +0 -0
  74. {atlas_init-0.1.0.dist-info → atlas_init-0.1.4.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import os
2
+ from collections.abc import Callable
2
3
  from pathlib import Path
3
4
 
4
5
  import dotenv
@@ -21,15 +22,18 @@ DEFAULT_PROFILES_PATH.mkdir(exist_ok=True, parents=True)
21
22
  DEFAULT_TF_PATH = ROOT_PATH / "tf"
22
23
  DEFAULT_CONFIG_PATH = ROOT_PATH / "atlas_init.yaml"
23
24
  DEFAULT_SCHEMA_CONFIG_PATH = ROOT_PATH / "terraform.yaml"
25
+ DEFAULT_GITHUB_CI_RUN_LOGS = ROOT_PATH / "github_ci_run_logs"
26
+ DEFAULT_GITHUB_SUMMARY_DIR = ROOT_PATH / "github_ci_summary"
24
27
 
25
28
 
26
29
  def load_dotenv(env_path: Path) -> dict[str, str]:
27
30
  return {k: v for k, v in dotenv.dotenv_values(env_path).items() if v}
28
31
 
29
32
 
30
- def dump_vscode_dotenv(generated_path: Path, vscode_env_path: Path) -> None:
33
+ def dump_vscode_dotenv(generated_path: Path, vscode_env_path: Path, **extras: str) -> None:
31
34
  vscode_env_vars = load_dotenv(generated_path)
32
35
  vscode_env_vars.pop("TF_CLI_CONFIG_FILE", None) # migration tests will use local provider instead of online
36
+ vscode_env_vars.update(extras)
33
37
  dump_dotenv(vscode_env_path, vscode_env_vars)
34
38
 
35
39
 
@@ -43,6 +47,13 @@ def current_dir():
43
47
  return Path(os.path.curdir).absolute()
44
48
 
45
49
 
50
+ def default_factory_cwd(rel_path: str) -> Callable[[], Path]:
51
+ def default_factory():
52
+ return current_dir() / rel_path
53
+
54
+ return default_factory
55
+
56
+
46
57
  def repo_path_rel_path() -> tuple[Path, str]:
47
58
  cwd = current_dir()
48
59
  rel_path = []
@@ -9,11 +9,48 @@ class _LogLevel(BaseModel):
9
9
  log_level: Literal["INFO", "WARNING", "ERROR", "CRITICAL"]
10
10
 
11
11
 
12
- def configure_logging(log_level: str = "INFO"):
12
+ def remove_secrets(message: str, secrets: list[str]) -> str:
13
+ for secret in secrets:
14
+ message = message.replace(secret, "***")
15
+ return message
16
+
17
+
18
+ class SecretsHider(logging.Filter):
19
+ def __init__(self, secrets: list[str], name: str = "") -> None:
20
+ self.secrets = secrets
21
+ super().__init__(name)
22
+
23
+ def filter(self, record: logging.LogRecord) -> bool:
24
+ record.msg = remove_secrets(record.msg, self.secrets)
25
+ return True
26
+
27
+
28
+ dangerous_keys = ["key", "id", "secret"]
29
+ safe_keys: list[str] = ["/"]
30
+
31
+
32
+ def hide_secrets(handler: logging.Handler, secrets_dict: dict[str, str]) -> None:
33
+ secrets_to_hide = set()
34
+ for key, value in secrets_dict.items():
35
+ if not isinstance(value, str):
36
+ continue
37
+ key_lower = key.lower()
38
+ if key_lower in {"true", "false"}:
39
+ continue
40
+ if any(safe in key_lower for safe in safe_keys):
41
+ continue
42
+ if any(danger in key_lower for danger in dangerous_keys):
43
+ secrets_to_hide.add(value)
44
+ handler.addFilter(SecretsHider(list(secrets_to_hide), name="secrets-hider"))
45
+
46
+
47
+ def configure_logging(log_level: str = "INFO") -> logging.Handler:
13
48
  _LogLevel(log_level=log_level) # type: ignore
49
+ handler = RichHandler(rich_tracebacks=True)
14
50
  logging.basicConfig(
15
51
  level=logging.getLevelName(log_level),
16
52
  format="%(message)s",
17
53
  datefmt="[%X]",
18
- handlers=[RichHandler(rich_tracebacks=True)],
54
+ handlers=[handler],
19
55
  )
56
+ return handler
atlas_init/terraform.yaml CHANGED
@@ -15,7 +15,7 @@ resources:
15
15
  - tags
16
16
  attributes:
17
17
  aliases:
18
- groupId: id
18
+ groupId: project_id
19
19
  create:
20
20
  path: /api/atlas/v2/groups
21
21
  method: POST
@@ -28,3 +28,79 @@ resources:
28
28
  delete:
29
29
  path: /api/atlas/v2/groups/{groupId}
30
30
  method: DELETE
31
+ - name: streamprocessor
32
+ extensions:
33
+ - type: rename_attribute
34
+ from_name: _id
35
+ to_name: id
36
+ - type: ignore_nested
37
+ path: "*.links"
38
+ - type: change_attribute_type
39
+ path: processor_name
40
+ new_value: required
41
+ - type: change_attribute_type
42
+ path: project_id
43
+ new_value: required
44
+ - type: skip_validators
45
+ provider_spec_attributes: []
46
+ schema:
47
+ ignores:
48
+ - name
49
+ - pretty
50
+ - envelope
51
+ - links
52
+ attributes: # (only works on path attributes)
53
+ aliases:
54
+ # _id: id
55
+ # name: processor_name
56
+ groupId: project_id
57
+ tenantName: instance_name
58
+ create:
59
+ path: /api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor
60
+ method: POST
61
+ read:
62
+ path: /api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}
63
+ method: GET
64
+ delete:
65
+ path: /api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}
66
+ method: DELETE
67
+ # update: not implemented yet
68
+ # path: api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor
69
+ # method: PATCH
70
+ data_sources:
71
+ - name: stream_processor
72
+ extensions:
73
+ - type: rename_attribute
74
+ from_name: _id
75
+ to_name: id
76
+ - type: rename_attribute
77
+ from_name: tenant_name
78
+ to_name: instance_name
79
+ - type: ignore_nested
80
+ path: "*.links"
81
+ - type: change_attribute_type
82
+ path: processor_name
83
+ new_value: required
84
+ - type: change_attribute_type
85
+ path: project_id
86
+ new_value: required
87
+ - type: skip_validators
88
+ # pagination attributes
89
+ # generating test files
90
+ read:
91
+ path: /api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}
92
+ method: GET
93
+ schema:
94
+ ignores:
95
+ - name
96
+ - pretty
97
+ - envelope
98
+ - links
99
+ attributes: # (only works on path attributes)
100
+ aliases:
101
+ groupId: project_id
102
+ - name: stream_processors
103
+ read:
104
+ # unable to extract the description here
105
+ path: /api/atlas/v2/groups/{groupId}/streams/{tenantName}/processors
106
+ method: GET
@@ -0,0 +1,125 @@
1
+ # This file is maintained automatically by "terraform init".
2
+ # Manual edits may be lost in future updates.
3
+
4
+ provider "registry.terraform.io/hashicorp/aws" {
5
+ version = "5.67.0"
6
+ constraints = "~> 5.0"
7
+ hashes = [
8
+ "h1:8wkuQvQiqjjm2+gQepy6xFBfimGoesKz1BPcVKWvED8=",
9
+ "zh:1259c8106c0a3fc0ed3b3eb814ab88d6a672e678b533f47d1bbbe3107949f43e",
10
+ "zh:226414049afd6d334cc16ff5d6cef23683620a9b56da67a21422a113d9cce4ab",
11
+ "zh:3c89b103aea20ef82a84e889abaeb971cb168de8292b61b34b83e807c40085a9",
12
+ "zh:3dd88e994fb7d7a6c6eafd3c01393274e4f776021176acea2e980f73fbd4acbc",
13
+ "zh:487e0dda221c84a20a143904c1cee4e63fce6c5c57c21368ea79beee87b108da",
14
+ "zh:7693bdcec8181aafcbda2c41c35b1386997e2c92b6f011df058009e4c8b300e1",
15
+ "zh:82679536250420f9e8e6edfd0fa9a1bab99a7f31fe5f049ac7a2e0d8c287b56f",
16
+ "zh:8685218dae921740083820c52afa66cdf14cf130539da1efd7d9a78bfb6ade64",
17
+ "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
18
+ "zh:9e553a3ec05eedea779d393447fc316689ba6c4d4d8d569b986898e6dbe58fee",
19
+ "zh:a36c24acd3c75bac8211fefde58c459778021eb871ff8339be1c26ad8fd67ee1",
20
+ "zh:ce48bd1e35d6f996f1a09d8f99e8084469b7fec5611e67a50a63e96375b87ebe",
21
+ "zh:d6c76a24205513725269e4783da14be9648e9086fb621496052f4b37d52d785e",
22
+ "zh:d95a31745affb178ea48fa8e0be94691a8f7507ea55c0d0a4b6e0a8ef6fcb929",
23
+ "zh:f061ce59fac1bc425c1092e6647ed4bb1b61824416041b46dbf336e01a63ad89",
24
+ ]
25
+ }
26
+
27
+ provider "registry.terraform.io/hashicorp/http" {
28
+ version = "3.4.2"
29
+ constraints = "3.4.2"
30
+ hashes = [
31
+ "h1:vaoPfsLm6mOk6avKTrWi35o+9p4fEeZAY3hzYoXVTfo=",
32
+ "zh:0ba051c9c8659ce0fec94a3d50926745f11759509c4d6de0ad5f5eb289f0edd9",
33
+ "zh:23e6760e8406fef645913bf47bfab1ca984c1c5805d2bb0ef8310b16913d29cd",
34
+ "zh:3c69fde4548bfe65b968534c4df8d699648c921d6a065b97fec5faece73a442b",
35
+ "zh:41c7f9a8c117704b7a8fa96a57ebfb92b72129d9625128eeb0dee7d5a09d1110",
36
+ "zh:59d09d2e00727df10565cc82a33250b44201fcd353eb2b1579507a5a0adcce18",
37
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
38
+ "zh:c95b2f63d4357b3068531b90d9dca62a32551d7693defb7ab14b650b5d139c57",
39
+ "zh:cc0a3bbd3026191b35f417d3a8f26bdfad376d15be9e8d99a8803487ca5b0105",
40
+ "zh:d1185c6abb3ba25123fb7df1ad7dbe2b9cd8f43962628da551040fbe1934656f",
41
+ "zh:dfb26fccab7ecdc150f67415e6cfe19d699dc43e8bf5722f36032b17b46a0fbe",
42
+ "zh:eb1fcc00073bc0463f64e49600a73d925b1a0c0ae5b94dd7b67d3ebac248a113",
43
+ "zh:ec9b9ad69cf790cb0603a1036d758063bbbc35c0c75f72dd04a1eddaf46ad010",
44
+ ]
45
+ }
46
+
47
+ provider "registry.terraform.io/hashicorp/local" {
48
+ version = "2.4.1"
49
+ constraints = "2.4.1"
50
+ hashes = [
51
+ "h1:gpp25uNkYJYzJVnkyRr7RIBVfwLs9GSq2HNnFpTRBg0=",
52
+ "zh:244b445bf34ddbd167731cc6c6b95bbed231dc4493f8cc34bd6850cfe1f78528",
53
+ "zh:3c330bdb626123228a0d1b1daa6c741b4d5d484ab1c7ae5d2f48d4c9885cc5e9",
54
+ "zh:5ff5f9b791ddd7557e815449173f2db38d338e674d2d91800ac6e6d808de1d1d",
55
+ "zh:70206147104f4bf26ae67d730c995772f85bf23e28c2c2e7612c74f4dae3c46f",
56
+ "zh:75029676993accd6bef933c196b2fad51a9ec8a69a847dbbe96ec8ebf7926cdc",
57
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
58
+ "zh:7d48d5999fe1fcdae9295a7c3448ac1541f5a24c474bd82df6d4fa3732483f2b",
59
+ "zh:b766b38b027f0f84028244d1c2f990431a37d4fc3ac645962924554016507e77",
60
+ "zh:bfc7ad301dada204cf51c59d8bd6a9a87de5fddb42190b4d6ba157d6e08a1f10",
61
+ "zh:c902b527702a8c5e2c25a6637d07bbb1690cb6c1e63917a5f6dc460efd18d43f",
62
+ "zh:d68ae0e1070cf429c46586bc87580c3ed113f76241da2b6e4f1a8348126b3c46",
63
+ "zh:f4903fd89f7c92a346ae9e666c2d0b6884c4474ae109e9b4bd15e7efaa4bfc29",
64
+ ]
65
+ }
66
+
67
+ provider "registry.terraform.io/hashicorp/null" {
68
+ version = "3.2.3"
69
+ hashes = [
70
+ "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=",
71
+ "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2",
72
+ "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d",
73
+ "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3",
74
+ "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f",
75
+ "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1",
76
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
77
+ "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301",
78
+ "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670",
79
+ "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed",
80
+ "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65",
81
+ "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd",
82
+ "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5",
83
+ ]
84
+ }
85
+
86
+ provider "registry.terraform.io/hashicorp/random" {
87
+ version = "3.6.3"
88
+ hashes = [
89
+ "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=",
90
+ "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451",
91
+ "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8",
92
+ "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe",
93
+ "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1",
94
+ "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36",
95
+ "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e",
96
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
97
+ "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30",
98
+ "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615",
99
+ "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad",
100
+ "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556",
101
+ "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0",
102
+ ]
103
+ }
104
+
105
+ provider "registry.terraform.io/mongodb/mongodbatlas" {
106
+ version = "1.19.0"
107
+ constraints = "1.19.0"
108
+ hashes = [
109
+ "h1:zzKWs4GzWXo+ImMQud/b0ECObJmbtB2wCrK3b98z1ms=",
110
+ "zh:3a8198e83b9b2dd1c461049f19464e82ce3f24d9fa7508e0e6dd642e2be70f73",
111
+ "zh:3a89a8395624a8e8516c6147b1612798f05e59ed3f13c1f6d8878099c9ca5f6e",
112
+ "zh:41ff89b10d5f1069d4bfa093e2d9297f1670863716f60d7b874f076bc37bc2ac",
113
+ "zh:5baf75906ccfc658be79b4c02c86032943af18c159f9c80a067ed696f23db527",
114
+ "zh:697aa8aebc5f4f8b6c42ba33bd1fec5ab8244555905bf6c6482ebf4733fe7976",
115
+ "zh:6d7fe4c2bca1e34e0c881266a463bbe16dd9a2934b7fa6d116c711a56b895f6f",
116
+ "zh:6dca00e357d04fbaeab6d2fa336c6704e289c076beef250a3cfe948a901bc4d4",
117
+ "zh:877a40cabcc49ee9fb40143dcbd6253d0c08ac1603a71e2cf2dde2d1fbfde574",
118
+ "zh:8a43a657196f4917f32f07ea91f056a2be6e7adb8a1fb7df4517ad9b71362c30",
119
+ "zh:91ef30b6020da3d5c5781ea6718b5f785c1eb3c7f4677343b31af2297d9f3558",
120
+ "zh:9bbc42509526c942db3979eaacd15b96ad454777993a0b002f908f9e9fcef51c",
121
+ "zh:b11fd160fcdd9cf7423283af7e0c3f0970b391b5a62ec30fe699ffdd54351896",
122
+ "zh:c297a0a188141741f14578cd8db41c309361e37b1b0904e635a7ebd0993e86f7",
123
+ "zh:c8af40986dbc42e77d0e34af7ea2d730cb87aa0471236392dbea0926ab95159a",
124
+ ]
125
+ }
atlas_init/tf/always.tf CHANGED
@@ -9,6 +9,7 @@ resource "random_password" "username" {
9
9
  }
10
10
 
11
11
  data "http" "myip" {
12
+ count = var.use_project_myip ? 1 : 0
12
13
  url = "https://ipv4.icanhazip.com"
13
14
  }
14
15
 
@@ -35,9 +36,17 @@ resource "mongodbatlas_project" "project" {
35
36
  org_id = var.org_id
36
37
 
37
38
  tags = local.tags
39
+ region_usage_restrictions = var.is_mongodbgov_cloud ? "GOV_REGIONS_ONLY" : null
40
+ project_owner_id = length(var.user_id) > 0 ? var.user_id : null
38
41
  }
39
42
 
40
43
  resource "mongodbatlas_project_ip_access_list" "mongo-access" {
44
+ count = var.use_project_myip ? 1 : 0
41
45
  project_id = mongodbatlas_project.project.id
42
- cidr_block = "${chomp(data.http.myip.response_body)}/32"
43
- }
46
+ cidr_block = "${chomp(data.http.myip[0].response_body)}/32"
47
+ }
48
+
49
+ data "mongodbatlas_atlas_user" "this" {
50
+ count = length(var.user_id) > 0 ? 1 : 0
51
+ user_id = var.user_id
52
+ }
atlas_init/tf/main.tf CHANGED
@@ -24,6 +24,9 @@ module "cfn" {
24
24
  atlas_private_key = var.atlas_private_key
25
25
  cfn_profile = local.cfn_profile
26
26
  tags = local.tags
27
+ aws_account_id = local.aws_account_id
28
+ use_kms_key = var.cfn_config.use_kms_key
29
+ aws_region = var.cfn_config.region
27
30
  }
28
31
 
29
32
  module "cluster" {
@@ -2,7 +2,7 @@ terraform {
2
2
  required_providers {
3
3
  mongodbatlas = {
4
4
  source = "mongodb/mongodbatlas"
5
- version = ">=1.4.3"
5
+ version = "1.19.0"
6
6
  }
7
7
  }
8
8
  required_version = ">= 1.0"
@@ -14,5 +14,7 @@ output "env_vars" {
14
14
  AWS_ACCESS_KEY_ID = var.aws_access_key_id
15
15
  AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key
16
16
  AWS_REGION = var.aws_region
17
+ AWS_REGION_LOWERCASE = var.aws_region
18
+ AWS_REGION_UPPERCASE = replace(upper(var.aws_region), "-", "_")
17
19
  }
18
20
  }
@@ -2,7 +2,10 @@ terraform {
2
2
  required_providers {
3
3
  mongodbatlas = {
4
4
  source = "mongodb/mongodbatlas"
5
- version = ">=1.4.3"
5
+ version = "1.19.0"
6
+ }
7
+ aws = {
8
+ source = "hashicorp/aws"
6
9
  }
7
10
  }
8
11
  required_version = ">= 1.0"
@@ -1,22 +1,3 @@
1
- variable "cfn_profile" {
2
- type = string
3
- }
4
- variable "atlas_public_key" {
5
- type = string
6
- }
7
-
8
- variable "atlas_private_key" {
9
- type = string
10
- }
11
-
12
- variable "atlas_base_url" {
13
- type = string
14
- }
15
-
16
- variable "tags" {
17
- type = map(string)
18
- }
19
-
20
1
  terraform {
21
2
  required_providers {
22
3
  aws = {
@@ -30,22 +11,52 @@ locals {
30
11
  resource_actions_yaml = file("${path.module}/resource_actions.yaml")
31
12
  services = yamldecode(local.services_yaml)
32
13
  resource_actions = yamldecode(local.resource_actions_yaml)
14
+ role_name = "cfn-execution-role-${var.cfn_profile}"
15
+ iam_policy_statement = {
16
+ Sid = "Original"
17
+ Action = local.resource_actions
18
+ Effect = "Allow"
19
+ Resource = "*"
20
+ }
21
+ iam_policy_statement_kms = {
22
+ Sid = "Extra"
23
+ Action = ["kms:Decrypt"]
24
+ Effect = "Allow"
25
+ Resource = try(aws_kms_key.this[0].arn, "invalid-arn-not-used")
26
+ }
27
+ iam_policy_statement_cloudwatch = {
28
+ Sid = "CloudwatchLogs"
29
+ Action = ["logs:*"]
30
+ Effect = "Allow"
31
+ Resource = "*"
32
+ }
33
+ iam_policy_statements = var.use_kms_key ? [local.iam_policy_statement, local.iam_policy_statement_kms, local.iam_policy_statement_cloudwatch] : [local.iam_policy_statement, local.iam_policy_statement_cloudwatch]
34
+ iam_role_policy_json = jsonencode({
35
+ Version = "2012-10-17"
36
+ Statement = local.iam_policy_statements
37
+ })
33
38
  }
34
39
 
35
40
  resource "aws_secretsmanager_secret" "cfn" {
36
41
  name = "cfn/atlas/profile/${var.cfn_profile}"
42
+ description = "Secrets for the cfn ${var.cfn_profile} profile"
37
43
  recovery_window_in_days = 0 # allow force deletion
38
44
  tags = var.tags
45
+ kms_key_id = var.use_kms_key ? aws_kms_key.this[0].arn : null
39
46
  }
47
+
40
48
  resource "aws_secretsmanager_secret_version" "cfn" {
41
49
  secret_id = aws_secretsmanager_secret.cfn.id
42
50
  secret_string = jsonencode({
43
- BaseUrl = var.atlas_base_url
44
- PublicKey = var.atlas_public_key
45
- PrivateKey = var.atlas_private_key
51
+ BaseUrl = var.atlas_base_url
52
+ PublicKey = var.atlas_public_key
53
+ PrivateKey = var.atlas_private_key
54
+ DebugClient = true
46
55
  })
47
56
  }
48
57
 
58
+ data "aws_caller_identity" "this" {}
59
+
49
60
  data "aws_iam_policy_document" "assume_role" {
50
61
  statement {
51
62
  actions = ["sts:AssumeRole"]
@@ -54,27 +65,22 @@ data "aws_iam_policy_document" "assume_role" {
54
65
  type = "Service"
55
66
  identifiers = local.services
56
67
  }
68
+ principals {
69
+ type = "AWS"
70
+ identifiers = [data.aws_caller_identity.this.arn] # Allow the terraform creator account to assume the role
71
+ }
57
72
  }
58
73
  }
59
74
 
60
75
  resource "aws_iam_role" "execution_role" {
61
- name = "cfn-execution-role-${var.cfn_profile}"
76
+ name = local.role_name
62
77
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
63
78
  max_session_duration = 8400
64
79
 
65
80
  inline_policy {
66
81
  name = "ResourceTypePolicy"
67
82
 
68
- policy = jsonencode({
69
- Version = "2012-10-17"
70
- Statement = [
71
- {
72
- Action = local.resource_actions
73
- Effect = "Allow"
74
- Resource = "*"
75
- },
76
- ]
77
- })
83
+ policy = local.iam_role_policy_json
78
84
 
79
85
  }
80
86
  }
@@ -89,3 +95,11 @@ output "env_vars" {
89
95
  CFN_EXAMPLE_EXECUTION_ROLE = aws_iam_role.execution_role.arn
90
96
  }
91
97
  }
98
+
99
+
100
+ output "info" {
101
+ value = {
102
+ kms_key_policy_json = local.kms_key_policy_json
103
+ iam_role_policy_json = local.iam_role_policy_json
104
+ }
105
+ }
@@ -0,0 +1,54 @@
1
+ locals {
2
+ account_principal = {
3
+ AWS = var.aws_account_id
4
+ }
5
+ kms_secretsmanager_condition = {
6
+ StringEquals = {
7
+ "kms:CallerAccount" = var.aws_account_id
8
+ "kms:ViaService" = "secretsmanager.${var.aws_region}.amazonaws.com"
9
+ }
10
+ }
11
+ kms_key_policy_json = jsonencode({
12
+ Version = "2012-10-17",
13
+ Statement = [
14
+ {
15
+ Sid = "Enable IAM User Permissions",
16
+ Effect = "Allow",
17
+ Principal = local.account_principal,
18
+ Action = "kms:*",
19
+ Resource = "*"
20
+ },
21
+ {
22
+ Sid = "Enable IAM User Permissions for Role",
23
+ Effect = "Allow",
24
+ Principal = {
25
+ AWS = "*"
26
+ }
27
+ Action = "kms:Decrypt",
28
+ Resource = "*"
29
+ Condition = {
30
+ StringEquals = {
31
+ "aws:PrincipalArn" = "arn:aws:iam::${var.aws_account_id}:role/${local.role_name}"
32
+ }
33
+ }
34
+ },
35
+ # { useful to check our example guide
36
+ # "Sid" : "Allow access through AWS Secrets Manager for all principals in the account that are authorized to use AWS Secrets Manager",
37
+ # "Effect" : "Allow",
38
+ # # "Principal" : { "AWS" : [aws_iam_role.execution_role.arn] },
39
+ # "Principal" : { "AWS" : "*" },
40
+ # "Action" : [
41
+ # "kms:Decrypt",
42
+ # ],
43
+ # "Resource" : "*",
44
+ # "Condition" : local.kms_secretsmanager_condition
45
+ # },
46
+ ]
47
+ })
48
+ }
49
+ resource "aws_kms_key" "this" {
50
+ count = var.use_kms_key ? 1 : 0
51
+ description = "KMS key for ${var.cfn_profile}"
52
+ deletion_window_in_days = 7
53
+ policy = local.kms_key_policy_json
54
+ }
@@ -2,6 +2,7 @@
2
2
  - "secretsmanager:PutSecretValue"
3
3
  - "ec2:CreateVpcEndpoint"
4
4
  - "ec2:DeleteVpcEndpoints"
5
+ - "ec2:DescribeVpcEndpoints"
5
6
  - "cloudformation:CreateResource"
6
7
  - "cloudformation:DeleteResource"
7
8
  - "cloudformation:GetResource"
@@ -0,0 +1,31 @@
1
+ variable "cfn_profile" {
2
+ type = string
3
+ }
4
+ variable "atlas_public_key" {
5
+ type = string
6
+ }
7
+
8
+ variable "atlas_private_key" {
9
+ type = string
10
+ }
11
+
12
+ variable "atlas_base_url" {
13
+ type = string
14
+ }
15
+
16
+ variable "tags" {
17
+ type = map(string)
18
+ }
19
+
20
+ variable "use_kms_key" {
21
+ type = bool
22
+ default = false
23
+ }
24
+
25
+ variable "aws_account_id" {
26
+ type = string
27
+ }
28
+
29
+ variable "aws_region" {
30
+ type = string
31
+ }
@@ -49,6 +49,7 @@ EOF
49
49
  output "env_vars" {
50
50
  value = {
51
51
  IAM_ROLE_ID = mongodbatlas_cloud_provider_access_authorization.auth_role.role_id
52
+ AWS_IAM_ROLE_ARN = aws_iam_role.aws_role.arn
52
53
  }
53
54
  }
54
55
 
@@ -2,7 +2,7 @@ terraform {
2
2
  required_providers {
3
3
  mongodbatlas = {
4
4
  source = "mongodb/mongodbatlas"
5
- version = ">=1.4.3"
5
+ version = "1.19.0"
6
6
  }
7
7
  aws = {
8
8
  source = "hashicorp/aws"