├── .gitignore
├── tfquery
├── __init__.py
├── tfstate_v3_migration.py
├── utils.py
├── __main__.py
├── tfstate.py
├── tfplan.py
└── sql_handler.py
├── sample-data
├── README.md
├── terraform-terragoat-aws-tfstate-sentinel-mocks
│ ├── sentinel.json
│ ├── mock-tfrun.sentinel
│ ├── mock-tfstate-v2.sentinel
│ ├── mock-tfstate.sentinel
│ ├── mock-tfconfig.sentinel
│ └── mock-tfconfig-v2.sentinel
└── terraform-sample-aws.tfplan
├── setup.py
├── LICENSE.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | internal-tests/
3 | *.egg-info
4 | build/
5 | *.egg
6 | venv/
7 |
--------------------------------------------------------------------------------
/tfquery/__init__.py:
--------------------------------------------------------------------------------
1 | import tfquery.tfstate
2 | import tfquery.tfplan
3 | import tfquery.sql_handler
4 | import tfquery.tfstate_v3_migration
5 | import tfquery.utils
6 |
--------------------------------------------------------------------------------
/sample-data/README.md:
--------------------------------------------------------------------------------
1 | # Sample Data for tfquery
2 |
3 | ## Sample data for testing tfquery.
4 |
5 | * **terraform-terragoat-aws.tfstate**: Terraform state for file Terragoat AWS environment.
6 | * **terraform-terragoat-aws-tfstate-sentinel-mocks**: Sentinel mocks for Terragoat AWS environment.
7 |
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/sentinel.json:
--------------------------------------------------------------------------------
1 | {
2 | "mock": {
3 | "tfconfig": "mock-tfconfig.sentinel",
4 | "tfconfig/v1": "mock-tfconfig.sentinel",
5 | "tfconfig/v2": "mock-tfconfig-v2.sentinel",
6 | "tfplan": "mock-tfplan.sentinel",
7 | "tfplan/v1": "mock-tfplan.sentinel",
8 | "tfplan/v2": "mock-tfplan-v2.sentinel",
9 | "tfrun": "mock-tfrun.sentinel",
10 | "tfstate": "mock-tfstate.sentinel",
11 | "tfstate/v1": "mock-tfstate.sentinel",
12 | "tfstate/v2": "mock-tfstate-v2.sentinel"
13 | }
14 | }
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 |
4 | setup(name='tfquery',
5 | version='0.3.0',
6 | author='Mazin Ahmed',
7 | author_email='mazin@mazinahmed.net',
8 | packages=['tfquery'],
9 | entry_points={'console_scripts': ['tfquery=tfquery.__main__:main']},
10 | url='http://github.com/mazen160/tfquery',
11 | license='LICENSE.md',
12 | description='tfquery: Run SQL queries on your Terraform infrastructure. Query resources and analyze its configuration using a SQL-powered framework.',
13 | long_description=open('README.md').read(),
14 | long_description_content_type = "text/markdown")
15 |
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/mock-tfrun.sentinel:
--------------------------------------------------------------------------------
1 | id = "run-dZrrVZJeZDuBBDzu"
2 | created_at = "2021-04-24T19:36:28.501Z"
3 | message = "Queued manually using Terraform"
4 | commit_sha = undefined
5 | speculative = false
6 | is_destroy = false
7 | target_addrs = null
8 |
9 | variables = {
10 | "AWS_ACCESS_KEY_ID": {
11 | "category": "terraform",
12 | "sensitive": false,
13 | },
14 | "AWS_SECRET_ACCESS_KEY": {
15 | "category": "terraform",
16 | "sensitive": true,
17 | },
18 | }
19 |
20 | organization = {
21 | "name": "X",
22 | }
23 |
24 | workspace = {
25 | "auto_apply": false,
26 | "created_at": "2021-04-24T19:14:32.703Z",
27 | "description": null,
28 | "id": "ws-yXFrJ7NgCSCdTfCb",
29 | "name": "Workspace",
30 | "vcs_repo": null,
31 | "working_directory": "",
32 | }
33 |
34 | cost_estimate = {
35 | "delta_monthly_cost": "71.66200000000000248",
36 | "prior_monthly_cost": "0.0",
37 | "proposed_monthly_cost": "71.66200000000000248",
38 | }
39 |
--------------------------------------------------------------------------------
/tfquery/tfstate_v3_migration.py:
--------------------------------------------------------------------------------
1 | def get_resources(tfstate):
2 | def __get_name(k):
3 | s = k.split(".")
4 | del s[0]
5 | return ".".join(s)
6 | output = []
7 | for a in tfstate["modules"]:
8 | for b in a["resources"]:
9 | data = {"type": None, "path": None, "mode": "version_3", "name": None, "provider": None, "instances": []}
10 | data["path"] = "/".join(a["path"])
11 | data["type"] = a["resources"][b]["type"]
12 | data["name"] = __get_name(b)
13 | data["provider"] = a["resources"][b]["provider"]
14 |
15 | dependencies = a["resources"][b]["depends_on"]
16 | attributes = a["resources"][b]["primary"]["attributes"]
17 | data_object = {"attributes": attributes, "dependencies": dependencies}
18 |
19 | data["instances"].append(data_object)
20 | output.append(data)
21 | return output
22 |
23 |
24 | def upgrade_v3_tfstate(tfstate):
25 | tfstate["resources"] = get_resources(tfstate)
26 | tfstate["version"] = 4
27 | return tfstate
28 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 Mazin Ahmed
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 | OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tfquery/utils.py:
--------------------------------------------------------------------------------
1 | #!/usr/env python3
2 | from os import listdir
3 | from os.path import isfile
4 | from os.path import join
5 | import json
6 | import logging
7 |
8 |
9 | import tfquery.tfstate as tfstate
10 | import tfquery.tfplan as tfplan
11 | from tfquery.sql_handler import SQLHandler
12 |
13 |
14 | def get_all_tfstates(dir):
15 | onlyfiles = [join(dir, f) for f in listdir(dir) if isfile(join(dir, f))]
16 | output = []
17 | for i in onlyfiles:
18 | if i.endswith(".tfstate"):
19 | output.append(i)
20 | return output
21 |
22 | def import_tfstate(db_path, tfstate_file):
23 | logging.basicConfig(format='%(message)s')
24 | log = logging.getLogger("tfquery")
25 | log.info(f"[i] tfstate file: {tfstate_file}")
26 | resources = tfstate.parse_resources(tfstate_file, detailed=True)
27 | s = SQLHandler(hide_attributes=True, db_path=db_path, tfstate_file=tfstate_file)
28 | log.info(f"[i] DB Path: {s.db_path}")
29 |
30 | s.create_table(resources)
31 | s.insert_resources(resources)
32 | log.info(f"[+] Imported {len(resources)} resources from {tfstate_file}.")
33 |
34 | def import_tfplan(db_path, tfplan_file, include_no_op=False):
35 | logging.basicConfig(format='%(message)s')
36 | log = logging.getLogger("tfquery")
37 | log.info(f"[i] tfplan file: {tfplan_file}")
38 | changes = tfplan.parse_changes(tfplan_file, include_no_op=include_no_op)
39 | s = SQLHandler(hide_attributes=True, db_path=db_path, tfplan_file=tfplan_file)
40 | log.info(f"[i] DB Path: {s.db_path}")
41 |
42 | s.create_table([])
43 | for change in changes:
44 | s.insert_change(change)
45 | log.info(f"[+] Imported {len(changes)} changes from {tfplan_file}.")
46 |
47 | def beautify_json(j):
48 | return json.dumps(j, indent=4, sort_keys=True)
49 |
--------------------------------------------------------------------------------
/tfquery/__main__.py:
--------------------------------------------------------------------------------
1 | #!/usr/env python3
2 | import argparse
3 | import sys
4 | import logging
5 |
6 | from tfquery.sql_handler import SQLHandler
7 | import tfquery.utils as utils
8 | from tfquery.sql_handler import get_random_db_path
9 |
10 |
11 | def main():
12 | parser = argparse.ArgumentParser(
13 | description='tfquery-cli: Run SQL queries on your Terraform infrastructure.')
14 | parser.add_argument('--tfstate', dest='tfstate', action='store',
15 | help='Terraform .tfstate file.')
16 | parser.add_argument('--tfplan', dest='tfplan', action='store',
17 | help='Terraform tfplan JSON file.')
18 | parser.add_argument('--tfstate-dir', dest='tfstate_dir', action='store',
19 | help='Directory of Terraform .tfstate files, for running queries on environments.')
20 | parser.add_argument('--query', '-q', dest='query', action='store',
21 | help='SQL query to execute.')
22 | parser.add_argument('--db', dest='db_path', action='store',
23 | help='DB path (optional. default: temporarily-generated database).')
24 | parser.add_argument('--interactive', '-i', dest='interactive_mode', action='store_true',
25 | help='Interactive mode.')
26 | parser.add_argument('--import', dest='import_tf_file', action='store_true',
27 | help='Import tfstate and tfplan into database.')
28 | parser.add_argument('--include-tfplan-no-op', dest='include_tfplan_no_np', action='store_true',
29 | help='Include tfplan no-op actions.')
30 | args = parser.parse_args()
31 | logging.basicConfig(format='%(message)s')
32 | log = logging.getLogger("tfquery")
33 |
34 | if len(sys.argv) <= 1:
35 | log.error("tfquery-cli: Run with -h for help")
36 | exit(1)
37 |
38 | tfstates = []
39 | if args.tfstate:
40 | for f in args.tfstate.split(","):
41 | tfstates.append(f)
42 |
43 | if args.tfstate_dir:
44 | tfstates.extend(utils.get_all_tfstates(args.tfstate_dir))
45 |
46 | if len(tfstates) == 0 and args.import_tf_file and not args.tfplan:
47 | log.error("Terraform states are not provided. Run -h for help.")
48 | exit(1)
49 |
50 | if len(tfstates) == 0 and args.db_path is None and not args.tfplan:
51 | log.error("Both Terraform states and database are not specified.")
52 | exit(1)
53 |
54 | if args.db_path is None:
55 | args.db_path = get_random_db_path()
56 | args.import_tf_file = True
57 |
58 | if args.import_tf_file:
59 | for tfstate in tfstates:
60 | utils.import_tfstate(args.db_path, tfstate)
61 | if args.tfplan:
62 | utils.import_tfplan(args.db_path , args.tfplan, include_no_op=args.include_tfplan_no_np)
63 |
64 | if args.query:
65 | s = SQLHandler(hide_attributes=True, db_path=args.db_path)
66 | print()
67 | print(utils.beautify_json(s.query(args.query)))
68 |
69 | if args.interactive_mode:
70 | while True:
71 | print("%> ", end="")
72 | q = input()
73 | s = SQLHandler(hide_attributes=True, db_path=args.db_path)
74 | print()
75 | print(utils.beautify_json(s.query(q)))
76 |
77 | if __name__ == "__main__":
78 | main()
79 |
--------------------------------------------------------------------------------
/tfquery/tfstate.py:
--------------------------------------------------------------------------------
1 | from tfquery.tfstate_v3_migration import upgrade_v3_tfstate
2 | import json
3 | from tfquery.sql_handler import SQLHandler
4 | import logging
5 |
6 |
7 | def validate_tfstate(tfstate):
8 | if "terraform_version" not in tfstate.keys():
9 | raise ValueError("Invalid tfstate file")
10 | return False
11 | if tfstate["version"] < 3:
12 | raise ValueError("Unsupported tfstate version")
13 | return False
14 | return True
15 |
16 |
17 | def prepare_tfstate(tfstate):
18 | resources = []
19 | if tfstate["version"] == 3:
20 | tfstate = upgrade_v3_tfstate(tfstate)
21 | tfstate_updated = tfstate
22 |
23 | for i in tfstate["resources"]:
24 | data = {}
25 | data.update(i)
26 | if "module" not in data:
27 | data["module"] = "none"
28 | assert data["mode"]
29 | assert data["type"]
30 | assert data["name"]
31 | assert data["provider"]
32 | assert "instances" in data
33 | assert "module" in data
34 | resources.append(data)
35 | tfstate_updated["resources"] = resources
36 | return tfstate_updated
37 |
38 |
39 | def get_all_attributes(tfstate):
40 | attributes = []
41 | for i in tfstate["resources"]:
42 | for j in i["instances"]:
43 | attributes.extend(j["attributes"].keys())
44 |
45 | def lowercase_all(k):
46 | return [i.lower() for i in k]
47 |
48 | attributes = lowercase_all(attributes)
49 | attributes = list(set(attributes))
50 | return attributes
51 |
52 |
53 | def get_resources(tfstate):
54 | tfstate = prepare_tfstate(tfstate)
55 | resources = []
56 | for resource in tfstate["resources"]:
57 | for instance in resource["instances"]:
58 | data = {}
59 | data["mode"] = resource["mode"]
60 | data["type"] = resource["type"]
61 | data["name"] = resource["name"]
62 | data["provider"] = resource["provider"]
63 | data["module"] = resource["module"]
64 | data["attributes"] = instance["attributes"]
65 | if "dependencies" in instance:
66 | data["dependencies"] = instance["dependencies"]
67 | else:
68 | data["dependencies"] = []
69 | resources.append(data)
70 | return resources
71 |
72 |
73 | def get_detailed_resources(tfstate):
74 | resources = get_resources(tfstate)
75 | detailed_resources = []
76 | all_attributes = get_all_attributes(tfstate)
77 | for resource in resources:
78 | data = {}
79 | data.update(resource)
80 |
81 | for i in all_attributes:
82 | data["__" + i] = None
83 | for k in resource["attributes"].keys():
84 | data["__" + k] = resource["attributes"][k]
85 | detailed_resources.append(data)
86 | return detailed_resources
87 |
88 |
89 | def load_file(tfstate_file):
90 | f = open(tfstate_file, "r")
91 | tfstate = json.loads(f.read())
92 | f.close()
93 | return tfstate
94 |
95 |
96 | def parse_resources(tfstate_file, detailed=False):
97 | tfstate = load_file(tfstate_file)
98 | if validate_tfstate(tfstate) is False:
99 | return([])
100 | if detailed:
101 | resources = get_detailed_resources(tfstate)
102 | else:
103 | resources = get_resources(tfstate)
104 |
105 | return resources
106 |
107 |
108 | def run_query(tfstate_file, query):
109 | logging.basicConfig(format='%(message)s')
110 | log = logging.getLogger("tfquery")
111 | resources = parse_resources(tfstate_file)
112 | s = SQLHandler(tfstate_file=tfstate_file, in_memory=True)
113 | s.create_table(resources)
114 | s.insert_resources(resources)
115 | log.info(f">> {query}")
116 | res = s.query(query)
117 | s.remove_db()
118 | return res
119 |
--------------------------------------------------------------------------------
/tfquery/tfplan.py:
--------------------------------------------------------------------------------
1 | import json
2 | from tfquery.sql_handler import SQLHandler
3 | from tfquery.tfstate import load_file # API reference
4 | import logging
5 |
6 | def validate_tfplan(tfplan):
7 | if "terraform_version" not in tfplan.keys():
8 | raise ValueError("Invalid tfplan file")
9 | return False
10 | if "format_version" not in tfplan.keys():
11 | raise ValueError("Unsupported tfplan file")
12 | return False
13 | return True
14 |
15 | def __get_keys(res):
16 | if type(res) == dict:
17 | return res.keys()
18 | return []
19 |
20 | def prepare_tfplan(tfplan, include_no_op=False):
21 | resources = []
22 | for i in tfplan["resource_changes"]:
23 | data = {"address": None,
24 | "mode": None,
25 | "type": None,"name": None,
26 | "provider": None,
27 | "change_actions": {"actions": []},
28 | "change_before": {},
29 | "change_after": {},
30 | "diff_keys": []
31 | }
32 | # after_unknown, after_sensitive, before_sensitive
33 | # before_unknown is not there
34 |
35 | # check no-op actions
36 | is_no_op = True
37 | for j in i["change"]["actions"]:
38 | if j != "no-op":
39 | is_no_op = False
40 | if is_no_op and not include_no_op:
41 | continue
42 |
43 | data["address"] = i["address"]
44 | data["mode"] = i["mode"]
45 | data["type"] = i["type"]
46 | data["name"] = i["name"]
47 | data["provider"] = i["provider_name"]
48 | data["change_actions"]["actions"] = i["change"]["actions"]
49 | if i["change"]["before"]:
50 | data["change_before"] = i["change"]["before"]
51 | if i["change"]["after"]:
52 | data["change_after"] = i["change"]["after"]
53 | for k in __get_keys(i["change"]["after_unknown"]):
54 | data["change_after"].update({f"unknown__{k}": i["change"]["after_unknown"][k]})
55 | for k in __get_keys(i["change"]["after_sensitive"]):
56 | data["change_after"].update({f"sensitive__{k}": i["change"]["after_sensitive"][k]})
57 |
58 | for k in __get_keys(i["change"]["before_sensitive"]):
59 | data["change_before"].update({f"sensitive__{k}": i["change"]["before_sensitive"][k]})
60 |
61 | data["diff_keys"] = get_plan_diff_keys(data)
62 | for k in data["diff_keys"]:
63 | if k not in data["change_before"]:
64 | data["change_before"][k] = None
65 | if k not in data["change_after"]:
66 | data["change_after"][k] = None
67 |
68 | resources.append(data)
69 |
70 | return resources
71 |
72 |
73 | def parse_changes(tfplan_file, include_no_op=False):
74 | tfplan = load_file(tfplan_file)
75 | if validate_tfplan(tfplan) is False:
76 | return([])
77 | changes = prepare_tfplan(tfplan, include_no_op=include_no_op)
78 | return changes
79 |
80 |
81 | def run_query(tfplan_file, query, include_no_op=False):
82 | logging.basicConfig(format='%(message)s')
83 | log = logging.getLogger("tfquery")
84 | changes = parse_changes(tfplan_file, include_no_op=include_no_op)
85 | s = SQLHandler(tfplan_file=tfplan_file, in_memory=True)
86 | s.create_table([])
87 | for change in changes:
88 | s.insert_change(change)
89 | log.info(f">> {query}")
90 | res = s.query(query)
91 | s.remove_db()
92 | return res
93 |
94 | def get_plan_diff_keys(data):
95 | diff_keys = set()
96 | for k in data["change_before"].keys():
97 | if k not in __get_keys(data["change_after"]):
98 | diff_keys.add(k)
99 | continue
100 | if data["change_after"][k] != data["change_before"][k]:
101 | diff_keys.add(k)
102 |
103 | for k in __get_keys(data["change_after"]):
104 | if k not in __get_keys(data["change_before"]):
105 | diff_keys.add(k)
106 | continue
107 | if data["change_after"][k] != data["change_before"][k]:
108 | diff_keys.add(k)
109 |
110 | return list(diff_keys)
111 |
112 |
--------------------------------------------------------------------------------
/tfquery/sql_handler.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 | import json
3 | import os
4 | import uuid
5 |
6 |
7 | def get_random_db_path():
8 | return f"/tmp/.{uuid.uuid4()}.db"
9 |
10 |
11 | def dict_factory(cursor, row):
12 | d = {}
13 | for idx, col in enumerate(cursor.description):
14 | d[col[0]] = row[idx]
15 | return d
16 |
17 |
18 | class SQLHandler(object):
19 | def __init__(self, hide_attributes=True, db_path=None, in_memory=False, tfstate_file=None, tfplan_file=None):
20 | self.hide_attributes = hide_attributes
21 | self.db_path = db_path
22 | self.tfstate_file = tfstate_file
23 | self.tfplan_file = tfplan_file
24 | if self.db_path is None:
25 | self.db_path = get_random_db_path()
26 | if in_memory:
27 | self.db_path = "file::memory:"
28 | self.conn = self.get_new_db()
29 | self.conn.row_factory = dict_factory
30 | self.cursor = self.conn.cursor()
31 |
32 | def create_table(self, resources):
33 | if self.hide_attributes:
34 | resources = self.__hide_attributes(resources)
35 |
36 | # tfstate
37 | if len(resources) == 0:
38 | tfstate_columns = ['mode', 'type', 'name', 'provider', 'module', 'attributes', 'dependencies']
39 | else:
40 | tfstate_columns = list(resources[0].keys())
41 | tfstate_columns.append("tfstate_file")
42 | sql = "CREATE TABLE IF NOT EXISTS resources(\n"
43 | for i in enumerate(tfstate_columns):
44 | if i[1] in ("attributes", "dependencies"):
45 | sql += f"`{i[1]}` json default null"
46 | else:
47 | sql += f"`{i[1]}` text default null"
48 | if i[0] != len(tfstate_columns) - 1:
49 | sql += ",\n"
50 | sql += '\n)'
51 | self.cursor.execute(sql)
52 |
53 | # tfplan
54 | tfplan_columns = ['address', 'mode', 'type', 'name', 'provider', 'change_actions', 'change_before', 'change_after', 'diff_keys', "tfplan_file"]
55 | sql = "CREATE TABLE IF NOT EXISTS changes(\n"
56 | for i in enumerate(tfplan_columns):
57 | if i[1] in ("change_actions", "change_before", "change_after"):
58 | sql += f"`{i[1]}` json default null"
59 | else:
60 | sql += f"`{i[1]}` text default null"
61 | if i[0] != len(tfplan_columns) - 1:
62 | sql += ",\n"
63 | sql += '\n)'
64 | self.cursor.execute(sql)
65 |
66 | def get_new_db(self):
67 | self.conn = sqlite3.connect(self.db_path)
68 | return self.conn
69 |
70 | def remove_db(self):
71 | if self.db_path:
72 | if os.path.exists(self.db_path):
73 | os.remove(self.db_path)
74 |
75 | def return_db(self):
76 | return self.conn
77 |
78 | def query(self, sql, parse_attributes=True):
79 | self.cursor.execute(sql)
80 | res = self.cursor.fetchall()
81 | if parse_attributes is False:
82 | return res
83 | output = []
84 | for i in res:
85 | json_fields = "change_actions", "change_before", "change_after", "attributes", "dependencies", "diff_keys"
86 | for j in i.keys():
87 | if j in json_fields and i[j] is not None:
88 | i[j] = json.loads(i[j])
89 | output.append(i)
90 |
91 | return output
92 |
93 | def insert_resources(self, resources):
94 | if self.hide_attributes:
95 | resources = self.__hide_attributes(resources)
96 | for resource in resources:
97 | self.insert_resource(resource)
98 |
99 | def __hide_attributes(self, resources):
100 | output = []
101 | for resource in resources:
102 | new_resource = {}
103 | for j in resource.keys():
104 | if j.startswith("__"):
105 | continue
106 | new_resource[j] = resource[j]
107 | output.append(new_resource)
108 | return output
109 |
110 | def insert_resource(self, resource):
111 | tfstate_file = None
112 | if self.tfstate_file:
113 | tfstate_file = os.path.basename(self.tfstate_file)
114 | resource["tfstate_file"] = tfstate_file
115 |
116 |
117 | sql = "INSERT INTO resources("
118 | for i in enumerate(resource):
119 | sql += f"`{i[1]}`"
120 | sql += ", "
121 |
122 | sql = sql[0:-2]
123 | sql += ") VALUES ("
124 |
125 | for i in enumerate(resource):
126 | sql += f":{i[1]}"
127 | sql += ", "
128 | sql = sql[0:-2]
129 | sql += ");"
130 |
131 | for k in resource.keys():
132 | if type(resource[k]) not in [str, type(None)]:
133 | resource[k] = json.dumps(resource[k])
134 |
135 | try:
136 | self.cursor.execute(sql, resource)
137 | self.conn.commit()
138 | except Exception as e:
139 | print(e)
140 |
141 | def insert_change(self, change):
142 | tfplan_file = None
143 | if self.tfplan_file:
144 | tfplan_file = os.path.basename(self.tfplan_file)
145 |
146 | change["tfplan_file"] = tfplan_file
147 |
148 | columns = ['address', 'mode', 'type', 'name', 'provider', 'change_actions', 'change_before', 'change_after', "diff_keys", "tfplan_file"]
149 | sql = "INSERT INTO changes("
150 | for i in columns:
151 | sql += f"`{i}`"
152 | sql += ", "
153 | sql = sql[0:-2]
154 | sql += ") VALUES ("
155 |
156 | for i in columns:
157 | sql += f":{i}"
158 | sql += ", "
159 | sql = sql[0:-2]
160 | sql += ");"
161 | for k in change.keys():
162 | if type(change[k]) not in [str, type(None)]:
163 | change[k] = json.dumps(change[k])
164 |
165 | try:
166 | self.cursor.execute(sql, change)
167 | self.conn.commit()
168 | except Exception as e:
169 | print(e)
170 |
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/mock-tfstate-v2.sentinel:
--------------------------------------------------------------------------------
1 | terraform_version = "0.14.7"
2 |
3 | outputs = {
4 | "username": {
5 | "name": "username",
6 | "sensitive": false,
7 | "value": "123456789123-acme-dev-user",
8 | },
9 | }
10 |
11 | resources = {
12 | "aws_ami.amazon-linux-2": {
13 | "address": "aws_ami.amazon-linux-2",
14 | "depends_on": [],
15 | "deposed_key": "",
16 | "index": null,
17 | "mode": "data",
18 | "module_address": "",
19 | "name": "amazon-linux-2",
20 | "provider_name": "registry.terraform.io/hashicorp/aws",
21 | "tainted": false,
22 | "type": "aws_ami",
23 | "values": {
24 | "architecture": "x86_64",
25 | "arn": "arn:aws:ec2:us-west-1::image/ami-06d584c1805ad64fb",
26 | "block_device_mappings": [
27 | {
28 | "device_name": "/dev/xvda",
29 | "ebs": {
30 | "delete_on_termination": "true",
31 | "encrypted": "false",
32 | "iops": "0",
33 | "snapshot_id": "snap-0fbf7b35b6f00249f",
34 | "throughput": "0",
35 | "volume_size": "8",
36 | "volume_type": "standard",
37 | },
38 | "no_device": "",
39 | "virtual_name": "",
40 | },
41 | ],
42 | "creation_date": "2021-03-26T23:02:09.000Z",
43 | "description": "Amazon Linux 2 AMI 2.0.20210326.0 x86_64 HVM ebs",
44 | "ena_support": true,
45 | "executable_users": null,
46 | "filter": [
47 | {
48 | "name": "name",
49 | "values": [
50 | "amzn2-ami-hvm-*-x86_64-ebs",
51 | ],
52 | },
53 | {
54 | "name": "owner-alias",
55 | "values": [
56 | "amazon",
57 | ],
58 | },
59 | ],
60 | "hypervisor": "xen",
61 | "id": "ami-06d584c1805ad64fb",
62 | "image_id": "ami-06d584c1805ad64fb",
63 | "image_location": "amazon/amzn2-ami-hvm-2.0.20210326.0-x86_64-ebs",
64 | "image_owner_alias": "amazon",
65 | "image_type": "machine",
66 | "kernel_id": null,
67 | "most_recent": true,
68 | "name": "amzn2-ami-hvm-2.0.20210326.0-x86_64-ebs",
69 | "name_regex": null,
70 | "owner_id": "137112412989",
71 | "owners": [
72 | "amazon",
73 | ],
74 | "platform": null,
75 | "platform_details": "Linux/UNIX",
76 | "product_codes": [],
77 | "public": true,
78 | "ramdisk_id": null,
79 | "root_device_name": "/dev/xvda",
80 | "root_device_type": "ebs",
81 | "root_snapshot_id": "snap-0fbf7b35b6f00249f",
82 | "sriov_net_support": "simple",
83 | "state": "available",
84 | "state_reason": {
85 | "code": "UNSET",
86 | "message": "UNSET",
87 | },
88 | "tags": {},
89 | "usage_operation": "RunInstances",
90 | "virtualization_type": "hvm",
91 | },
92 | },
93 | "aws_caller_identity.current": {
94 | "address": "aws_caller_identity.current",
95 | "depends_on": [],
96 | "deposed_key": "",
97 | "index": null,
98 | "mode": "data",
99 | "module_address": "",
100 | "name": "current",
101 | "provider_name": "registry.terraform.io/hashicorp/aws",
102 | "tainted": false,
103 | "type": "aws_caller_identity",
104 | "values": {
105 | "account_id": "123456789123",
106 | "arn": "arn:aws:iam::123456789123:user/terraform-test",
107 | "id": "123456789123",
108 | "user_id": "AIDAT7X67JOMQS4DRTZRE",
109 | },
110 | },
111 | "aws_iam_policy_document.iam_policy_eks": {
112 | "address": "aws_iam_policy_document.iam_policy_eks",
113 | "depends_on": [],
114 | "deposed_key": "",
115 | "index": null,
116 | "mode": "data",
117 | "module_address": "",
118 | "name": "iam_policy_eks",
119 | "provider_name": "registry.terraform.io/hashicorp/aws",
120 | "tainted": false,
121 | "type": "aws_iam_policy_document",
122 | "values": {
123 | "id": "189502314",
124 | "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"eks.amazonaws.com\"\n }\n }\n ]\n}",
125 | "override_json": null,
126 | "override_policy_documents": null,
127 | "policy_id": null,
128 | "source_json": null,
129 | "source_policy_documents": null,
130 | "statement": [
131 | {
132 | "actions": [
133 | "sts:AssumeRole",
134 | ],
135 | "condition": [],
136 | "effect": "Allow",
137 | "not_actions": [],
138 | "not_principals": [],
139 | "not_resources": [],
140 | "principals": [
141 | {
142 | "identifiers": [
143 | "eks.amazonaws.com",
144 | ],
145 | "type": "Service",
146 | },
147 | ],
148 | "resources": [],
149 | "sid": "",
150 | },
151 | ],
152 | "version": "2012-10-17",
153 | },
154 | },
155 | "aws_iam_policy_document.policy": {
156 | "address": "aws_iam_policy_document.policy",
157 | "depends_on": [],
158 | "deposed_key": "",
159 | "index": null,
160 | "mode": "data",
161 | "module_address": "",
162 | "name": "policy",
163 | "provider_name": "registry.terraform.io/hashicorp/aws",
164 | "tainted": false,
165 | "type": "aws_iam_policy_document",
166 | "values": {
167 | "id": "3931805674",
168 | "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Action\": \"es:*\",\n \"Resource\": \"*\",\n \"Principal\": {\n \"AWS\": \"*\"\n }\n }\n ]\n}",
169 | "override_json": null,
170 | "override_policy_documents": null,
171 | "policy_id": null,
172 | "source_json": null,
173 | "source_policy_documents": null,
174 | "statement": [
175 | {
176 | "actions": [
177 | "es:*",
178 | ],
179 | "condition": [],
180 | "effect": "Allow",
181 | "not_actions": [],
182 | "not_principals": [],
183 | "not_resources": [],
184 | "principals": [
185 | {
186 | "identifiers": [
187 | "*",
188 | ],
189 | "type": "AWS",
190 | },
191 | ],
192 | "resources": [
193 | "*",
194 | ],
195 | "sid": "",
196 | },
197 | ],
198 | "version": "2012-10-17",
199 | },
200 | },
201 | }
202 |
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/mock-tfstate.sentinel:
--------------------------------------------------------------------------------
1 | import "strings"
2 | import "types"
3 |
4 | outputs = {
5 | "username": {
6 | "sensitive": false,
7 | "type": "string",
8 | "value": "123456789123-acme-dev-user",
9 | },
10 | }
11 |
12 | _modules = {
13 | "root": {
14 | "data": {
15 | "aws_ami": {
16 | "amazon-linux-2": {
17 | 0: {
18 | "attr": {
19 | "architecture": "x86_64",
20 | "arn": "arn:aws:ec2:us-west-1::image/ami-06d584c1805ad64fb",
21 | "block_device_mappings": [
22 | {
23 | "device_name": "/dev/xvda",
24 | "ebs": {
25 | "delete_on_termination": "true",
26 | "encrypted": "false",
27 | "iops": "0",
28 | "snapshot_id": "snap-0fbf7b35b6f00249f",
29 | "throughput": "0",
30 | "volume_size": "8",
31 | "volume_type": "standard",
32 | },
33 | "no_device": "",
34 | "virtual_name": "",
35 | },
36 | ],
37 | "creation_date": "2021-03-26T23:02:09.000Z",
38 | "description": "Amazon Linux 2 AMI 2.0.20210326.0 x86_64 HVM ebs",
39 | "ena_support": true,
40 | "executable_users": null,
41 | "filter": [
42 | {
43 | "name": "name",
44 | "values": [
45 | "amzn2-ami-hvm-*-x86_64-ebs",
46 | ],
47 | },
48 | {
49 | "name": "owner-alias",
50 | "values": [
51 | "amazon",
52 | ],
53 | },
54 | ],
55 | "hypervisor": "xen",
56 | "id": "ami-06d584c1805ad64fb",
57 | "image_id": "ami-06d584c1805ad64fb",
58 | "image_location": "amazon/amzn2-ami-hvm-2.0.20210326.0-x86_64-ebs",
59 | "image_owner_alias": "amazon",
60 | "image_type": "machine",
61 | "kernel_id": null,
62 | "most_recent": true,
63 | "name": "amzn2-ami-hvm-2.0.20210326.0-x86_64-ebs",
64 | "name_regex": null,
65 | "owner_id": "137112412989",
66 | "owners": [
67 | "amazon",
68 | ],
69 | "platform": null,
70 | "platform_details": "Linux/UNIX",
71 | "product_codes": [],
72 | "public": true,
73 | "ramdisk_id": null,
74 | "root_device_name": "/dev/xvda",
75 | "root_device_type": "ebs",
76 | "root_snapshot_id": "snap-0fbf7b35b6f00249f",
77 | "sriov_net_support": "simple",
78 | "state": "available",
79 | "state_reason": {
80 | "code": "UNSET",
81 | "message": "UNSET",
82 | },
83 | "tags": {},
84 | "usage_operation": "RunInstances",
85 | "virtualization_type": "hvm",
86 | },
87 | "depends_on": [],
88 | "id": "ami-06d584c1805ad64fb",
89 | "tainted": false,
90 | },
91 | },
92 | },
93 | "aws_caller_identity": {
94 | "current": {
95 | 0: {
96 | "attr": {
97 | "account_id": "123456789123",
98 | "arn": "arn:aws:iam::123456789123:user/terraform-test",
99 | "id": "123456789123",
100 | "user_id": "AIDAT7X67JOMQS4DRTZRE",
101 | },
102 | "depends_on": [],
103 | "id": "123456789123",
104 | "tainted": false,
105 | },
106 | },
107 | },
108 | "aws_iam_policy_document": {
109 | "iam_policy_eks": {
110 | 0: {
111 | "attr": {
112 | "id": "189502314",
113 | "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"eks.amazonaws.com\"\n }\n }\n ]\n}",
114 | "override_json": null,
115 | "override_policy_documents": null,
116 | "policy_id": null,
117 | "source_json": null,
118 | "source_policy_documents": null,
119 | "statement": [
120 | {
121 | "actions": [
122 | "sts:AssumeRole",
123 | ],
124 | "condition": [],
125 | "effect": "Allow",
126 | "not_actions": [],
127 | "not_principals": [],
128 | "not_resources": [],
129 | "principals": [
130 | {
131 | "identifiers": [
132 | "eks.amazonaws.com",
133 | ],
134 | "type": "Service",
135 | },
136 | ],
137 | "resources": [],
138 | "sid": "",
139 | },
140 | ],
141 | "version": "2012-10-17",
142 | },
143 | "depends_on": [],
144 | "id": "189502314",
145 | "tainted": false,
146 | },
147 | },
148 | "policy": {
149 | 0: {
150 | "attr": {
151 | "id": "3931805674",
152 | "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Action\": \"es:*\",\n \"Resource\": \"*\",\n \"Principal\": {\n \"AWS\": \"*\"\n }\n }\n ]\n}",
153 | "override_json": null,
154 | "override_policy_documents": null,
155 | "policy_id": null,
156 | "source_json": null,
157 | "source_policy_documents": null,
158 | "statement": [
159 | {
160 | "actions": [
161 | "es:*",
162 | ],
163 | "condition": [],
164 | "effect": "Allow",
165 | "not_actions": [],
166 | "not_principals": [],
167 | "not_resources": [],
168 | "principals": [
169 | {
170 | "identifiers": [
171 | "*",
172 | ],
173 | "type": "AWS",
174 | },
175 | ],
176 | "resources": [
177 | "*",
178 | ],
179 | "sid": "",
180 | },
181 | ],
182 | "version": "2012-10-17",
183 | },
184 | "depends_on": [],
185 | "id": "3931805674",
186 | "tainted": false,
187 | },
188 | },
189 | },
190 | },
191 | "path": [],
192 | "resources": {},
193 | },
194 | }
195 |
196 | module_paths = [
197 | [],
198 | ]
199 |
200 | terraform_version = "0.14.7"
201 |
202 | module = func(path) {
203 | if types.type_of(path) is not "list" {
204 | error("expected list, got", types.type_of(path))
205 | }
206 |
207 | if length(path) < 1 {
208 | return _modules.root
209 | }
210 |
211 | addr = []
212 | for path as p {
213 | append(addr, "module")
214 | append(addr, p)
215 | }
216 |
217 | return _modules[strings.join(addr, ".")]
218 | }
219 |
220 | data = _modules.root.data
221 | path = _modules.root.path
222 | resources = _modules.root.resources
223 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌩️ tfquery 🌩️
2 |
3 | ## Run SQL queries on your Terraform infrastructure. Ask questions that are hard to answer
4 |
5 |
6 |
7 |
8 |
9 |
10 | ---
11 |
12 | # 🚀 What is tfquery?
13 |
14 | tfquery is a framework that allows running SQL queries on Terraform code. It's made to analyze your Terraform infrastructure, locate resources, run security compliance checks, spot misconfigured resources, develop CI benchmarks, and much more.
15 |
16 | tfquery is made to help in answering questions that are hard to answer about your infrastructure-as-code. It allows querying resources and analyzing its configuration using a SQL-powered framework.
17 |
18 | # Why?
19 |
20 | infrastructure-as-code is the de-facto today for documenting and deploying infrastructure on cloud providers. As the organization grows, it becomes really hard to understand and analyze the deployed infrastructure. Grepping and searching for resources in Terraform state files is not enough. Terraform Modules are automating processes dynamically for infrastructure deployment, so searching for static resources is also not feasible for good visibility.
21 |
22 | With tfquery, you can run SQL queries on Terraform state files, and gain the best possible visibility.
23 |
24 | ---
25 |
26 | # 💡 Use tfquery to
27 |
28 | - Have full coverage of your infrastructure, without being locked on a specific provider, including Amazon AWS, Microsoft Azure, Google Cloud Platform, Alibaba Cloud, IBM Cloud, Oracle Cloud, and many others.
29 |
30 | - Analyze deployed resources configuration.
31 |
32 | - Develop CI and monitoring checks for cloud infrastructure.
33 |
34 | - Write custom queries to scan Terraform resources.
35 |
36 | - Scan current Terraform plan for new risky changes.
37 |
38 | ---
39 |
40 | # tfquery vs. Cloud-specific SQL engines?
41 |
42 | There are cloud-specific SQL engines that allow you to run SQL queries to understand resources on their infrastructure, both are covered as provided service by the cloud provider, or given as an open-source tool or a product. The main difference tfquery brings:
43 |
44 | - **Maintainability**: Cloud-specific SQL engines require maintenance in case of new services or breaking changes to existing ones. tfquery make use of Terraform schemas as a standard. tfquery will work on all given services, without the need to continuously update it with new API specs.
45 |
46 | - **Coverage**: tfquery covers all the cloud providers that Terraform supports out of the box (thanks to Terraform Providers).
47 |
48 | ---
49 |
50 | # 📖 Usage
51 |
52 |
53 | ## tfstate
54 |
55 | #### Run SQL query on Terraform states
56 |
57 | ```python
58 | >>> import tfquery
59 | >>>
60 | >>> result = tfquery.tfstate.run_query("terraform.tfstate", "select count(*) from resources")
61 | >> print(result)
62 | [{'count(*)': 86}]
63 | ```
64 |
65 | #### Parse all resources from a Terraform state file
66 |
67 | ```python
68 | >>> import tfquery
69 | >>>
70 | >>> resources = tfquery.tfstate.parse_resources("terraform.tfstate")
71 | >>> print(f"[i] Resources Count: {len(resources)}")
72 | [i] Resources Count: 1475
73 | ```
74 |
75 |
76 | ## Advanced Usage
77 |
78 | ### Migrate Version 3 to Version 4 Terraform states
79 |
80 | This is a parsing library to migrate the older Version 3 Terraform states to a Version 4 state. This is made to add backward compatibility for Terraform states that is made for releases older than `Terraform v0.11`.
81 |
82 | ```python
83 | >>> import tfquery
84 | >>>
85 | >>> tfstate_v3 = tfquery.tfstate.load_file("terraform.tfstate")
86 | >>> tfstate_v4 = tfquery.tfstate_v3_migration.upgrade_v3_tfstate(tfstate)
87 |
88 | ```
89 |
90 | ## tfplan
91 |
92 | #### Run SQL queries on Terraform changes through Terraform Plan (tfplan)
93 |
94 | 1) Save the Terraform plan
95 |
96 | ```
97 | $ terraform plan -out saved.plan
98 | $ terraform show -json saved.json > current.tfplan
99 | ```
100 |
101 | 2) Run tfquery on the Terraform Plan
102 |
103 | ```python
104 | >>> import tfquery
105 |
106 | >>> result = tfquery.tfplan.run_query("current.tfplan", "select count(*) from changes")
107 | >> print(result)
108 | [{'count(*)': 10}]
109 | ```
110 |
111 |
112 | ## 🖲️ Command-Line (`tfquery`)
113 |
114 | TFquery is also available as a CLI tool. It can be used to run SQL queries directly on Terraform states, and for importing resources into persistent storage.
115 |
116 | ```shell
117 | mazin@hackbox$> tfquery -h
118 | usage: tfquery [-h] [--tfstate TFSTATE] [--tfplan TFPLAN] [--tfstate-dir TFSTATE_DIR] [--query QUERY] [--db DB_PATH] [--interactive] [--import] [--include-tfplan-no-op]
119 |
120 | tfquery-cli: Run SQL queries on your Terraform infrastructure.
121 |
122 | optional arguments:
123 | -h, --help show this help message and exit
124 | --tfstate TFSTATE Terraform .tfstate file.
125 | --tfplan TFPLAN Terraform tfplan JSON file.
126 | --tfstate-dir TFSTATE_DIR
127 | Directory of Terraform .tfstate files, for running queries on environments.
128 | --query QUERY, -q QUERY
129 | SQL query to execute.
130 | --db DB_PATH DB path (optional. default: temporarily-generated database).
131 | --interactive, -i Interactive mode.
132 | --import Import tfstate and tfplan into database.
133 | --include-tfplan-no-op
134 | Include tfplan no-op actions.
135 |
136 | ```
137 |
138 | ### Examples
139 |
140 | - **Run SQL query for a directory of multiple Terraform states (for multiple workspaces).**
141 |
142 | ```python
143 | $ tfquery -q 'select count(*) as count from resources;' --tfstate-dir /path/to/terraform-states
144 | [i] DB Path: tfstate.db
145 | [+] Imported 4203 resources from ./prod.tfstate.
146 | [i] DB Path: tfstate.db
147 | [+] Imported 3675 resources from ./nonprod.tfstate.
148 | [i] DB Path: tfstate.db
149 | [+] Imported 463 resources from ./qa.tfstate.
150 | ```
151 |
152 | - **Import Terraform states into Database.**:
153 |
154 | ```python
155 | $ python3 tfquery --tfstate /path/to/terraform.state --db tfstate.db --import
156 | [i] DB Path: tfstate.db
157 | [+] Imported 386 resources from terraform.tfstate.
158 | ```
159 |
160 | - **Run queries on imported resources in a database**
161 |
162 | ```python
163 | $ tfquery --db tfstate.db -q 'select count(*) as count from resources;'
164 | [
165 | {
166 | "count": 386
167 | }
168 | ]
169 | ```
170 | - **Run Tfplan queries on current changes**
171 |
172 | ```python
173 | $ terraform plan -out saved.plan
174 | $ terraform show -json saved.json > current.tfplan
175 |
176 | $ tfquery --tfplan current.tfplan -q "select count(*) as count from changes"
177 |
178 | [
179 | {
180 | "count": 10
181 | }
182 | ]
183 | ```
184 |
185 | ---
186 |
187 | # 💭 Awesome Queries & Scripts
188 |
189 | **Find all AWS S3 buckets without versioning being enabled**
190 |
191 | ```python
192 | import tfquery, sys
193 | results = tfquery.tfstate.run_query(sys.argv[1], "select * from resources where type = 'aws_s3_bucket'")
194 | for result in results:
195 | attributes = result["attributes"]
196 | if 'versioning' not in attributes or len(attributes["versioning"]) == 0:
197 | # print(result)
198 | continue
199 | for versioning in attributes["versioning"]:
200 | if versioning["enabled"] is False:
201 | # print(result)
202 | pass
203 | ```
204 |
205 | **Find all AWS IAM users, and print their ARNs**
206 |
207 | ```python
208 | import tfquery, sys
209 | results = tfquery.tfstate.run_query(sys.argv[1], "select json_extract(attributes, '$.arn') as arn from resources where type = 'aws_iam_user';")
210 | for result in results:
211 | print(result["arn"])
212 | ```
213 |
214 | or
215 |
216 | ```python
217 | import tfquery, sys
218 | results = tfquery.tfstate.run_query(sys.argv[1], "select attributes from resources where type = 'aws_iam_user';")
219 | for result in results:
220 | print(result["attributes"]["arn"])
221 | ```
222 |
223 | **Find all resources in the environment, and show how many instances were deployed**
224 |
225 | ```python
226 | import tfquery
227 | results = tfquery.tfstate.run_query("terraform.tfstate", "select type, count(*) as count from resources group by type order BY count desc;")
228 | print(results)
229 | ```
230 |
231 | ---
232 |
233 | # ✨ Interested in tfquery?
234 |
235 | 1. **Post a Tweet about the project and tag [`@mazen160`](https://twitter.com/mazen160) 🙏**
236 |
237 | 2. **🌟 Star it on Github 🌟**
238 |
239 | 3. **Create a PR for a new awesome feature 💛**
240 |
241 | 4. **Would like to sponsor the project? Contact me on email!**
242 |
243 | ---
244 |
245 | # 💻 Contribution
246 |
247 | Contribution is always welcome! Please feel free to report issues on Github and create PRs for new features.
248 |
249 | ## 📌 Ideas to Start on
250 |
251 | Would like to contribute to tfquery? Here are some ideas that you may start with:
252 |
253 | - Better documentation: would be great to enhance the documentation with additional examples and queries.
254 |
255 | - CI: Implement CI along with test terraform states for Terragoat.
256 |
257 | - Support dependencies for resources lookup: Create a new table called "dependencies", parse V4 Terraform states, and implement a many-to-one relation for dependencies of resources.
258 |
259 | - More V3 --> V4 migration support: currently V3 resources migrations are supported. Dependencies are not migrated to the new V4 state. It will be great to continue on V3--> V4 support for Terraform states.
260 |
261 | - General validation of Terraform states parser implementation: Validate current implementation of the parser, and enhance it where possible.
262 |
263 | - [x] ~~Connect resources with terraform state base name: For environments with many workspaces, each workspace can have a different name, it would be nice to add a column for terraform state file base name, to help in querying across different workspaces.~~
264 |
265 | - [x] ~~tfplan parsing: Allow parsing of tfplan files. This can be an opening addition for implementing a new CI security scanner for Terraform deployments.~~
266 |
267 | - Logo design: a logo design would be great.
268 |
269 | - Web interface representation with [coleifer/sqlite-web](https://github.com/coleifer/sqlite-web) - Thanks [@securityfu](https://twitter.com/securityfu/) for the idea!
270 |
271 | - Add a managed repository of pre-defined queries to enable teams to be able to query Terraform for different compliance and security controls.
272 |
273 |
274 | ### As you can see, there are many ways to support. Please help us make the project bigger for everyone!
275 |
276 | ---
277 |
278 | # Installation
279 |
280 | ```shell
281 |
282 | mazin@hackbox$> git clone https://github.com/mazen160/tfquery.git
283 | mazin@hackbox$> cd tfquery
284 | mazin@hackbox$> python3 setup.py install
285 |
286 | ```
287 |
288 | or
289 |
290 | ```shell
291 | mazin@hackbox$> pip install git+https://github.com/mazen160/tfquery
292 | ```
293 |
294 | ---
295 |
296 | # 📄 License
297 |
298 | The project is licensed under MIT License.
299 |
300 | # 💚 Author
301 |
302 | **Mazin Ahmed**
303 |
304 | - **Website**: [https://mazinahmed.net](https://mazinahmed.net)
305 | - **Email**: `mazin [at] mazinahmed [dot] net`
306 | - **Twitter**: [https://twitter.com/mazen160](https://twitter.com/mazen160)
307 | - **Linkedin**: [http://linkedin.com/in/infosecmazinahmed](http://linkedin.com/in/infosecmazinahmed)
308 |
--------------------------------------------------------------------------------
/sample-data/terraform-sample-aws.tfplan:
--------------------------------------------------------------------------------
1 | {
2 | "format_version": "0.2",
3 | "terraform_version": "1.0.2",
4 | "planned_values": {
5 | "root_module": {
6 | "resources": [{
7 | "address": "aws_iam_policy.policy",
8 | "mode": "managed",
9 | "type": "aws_iam_policy",
10 | "name": "policy",
11 | "provider_name": "registry.terraform.io/hashicorp/aws",
12 | "schema_version": 0,
13 | "values": {
14 | "description": "My test policy",
15 | "name": "test_policy",
16 | "name_prefix": null,
17 | "path": "/",
18 | "policy": "{\"Statement\":[{\"Action\":[\"ec2:Describe*\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}],\"Version\":\"2012-10-17\"}",
19 | "tags": null
20 | },
21 | "sensitive_values": {
22 | "tags_all": {}
23 | }
24 | },
25 | {
26 | "address": "aws_s3_bucket.b",
27 | "mode": "managed",
28 | "type": "aws_s3_bucket",
29 | "name": "b",
30 | "provider_name": "registry.terraform.io/hashicorp/aws",
31 | "schema_version": 0,
32 | "values": {
33 | "acl": "private",
34 | "bucket": "my-tf-test-bucket",
35 | "bucket_prefix": null,
36 | "cors_rule": [],
37 | "force_destroy": false,
38 | "grant": [],
39 | "lifecycle_rule": [],
40 | "logging": [],
41 | "policy": null,
42 | "replication_configuration": [],
43 | "server_side_encryption_configuration": [],
44 | "tags": {
45 | "Environment": "Dev",
46 | "Name": "My bucket"
47 | },
48 | "tags_all": {
49 | "Environment": "Dev",
50 | "Name": "My bucket"
51 | },
52 | "website": []
53 | },
54 | "sensitive_values": {
55 | "cors_rule": [],
56 | "grant": [],
57 | "lifecycle_rule": [],
58 | "logging": [],
59 | "object_lock_configuration": [],
60 | "replication_configuration": [],
61 | "server_side_encryption_configuration": [],
62 | "tags": {},
63 | "tags_all": {},
64 | "versioning": [],
65 | "website": []
66 | }
67 | },
68 | {
69 | "address": "aws_vpc.example",
70 | "mode": "managed",
71 | "type": "aws_vpc",
72 | "name": "example",
73 | "provider_name": "registry.terraform.io/hashicorp/aws",
74 | "schema_version": 1,
75 | "values": {
76 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
77 | "assign_generated_ipv6_cidr_block": false,
78 | "cidr_block": "10.0.0.0/16",
79 | "default_network_acl_id": "acl-00ff509137be0c29b",
80 | "default_route_table_id": "rtb-000f91dc68252e8d5",
81 | "default_security_group_id": "sg-0a2b0e570b6328288",
82 | "dhcp_options_id": "dopt-6310d108",
83 | "enable_classiclink": false,
84 | "enable_classiclink_dns_support": false,
85 | "enable_dns_hostnames": false,
86 | "enable_dns_support": true,
87 | "id": "vpc-03d4fae1af7ddbe72",
88 | "instance_tenancy": "default",
89 | "ipv4_ipam_pool_id": null,
90 | "ipv4_netmask_length": null,
91 | "ipv6_association_id": "",
92 | "ipv6_cidr_block": "",
93 | "ipv6_cidr_block_network_border_group": "",
94 | "ipv6_ipam_pool_id": "",
95 | "ipv6_netmask_length": 0,
96 | "main_route_table_id": "rtb-000f91dc68252e8d5",
97 | "owner_id": "123456789123",
98 | "tags": {},
99 | "tags_all": {}
100 | },
101 | "sensitive_values": {
102 | "tags": {},
103 | "tags_all": {}
104 | }
105 | }
106 | ]
107 | }
108 | },
109 | "resource_drift": [{
110 | "address": "aws_vpc.example",
111 | "mode": "managed",
112 | "type": "aws_vpc",
113 | "name": "example",
114 | "provider_name": "registry.terraform.io/hashicorp/aws",
115 | "change": {
116 | "actions": [
117 | "update"
118 | ],
119 | "before": {
120 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
121 | "assign_generated_ipv6_cidr_block": false,
122 | "cidr_block": "10.0.0.0/16",
123 | "default_network_acl_id": "acl-00ff509137be0c29b",
124 | "default_route_table_id": "rtb-000f91dc68252e8d5",
125 | "default_security_group_id": "sg-0a2b0e570b6328288",
126 | "dhcp_options_id": "dopt-6310d108",
127 | "enable_classiclink": false,
128 | "enable_classiclink_dns_support": false,
129 | "enable_dns_hostnames": false,
130 | "enable_dns_support": true,
131 | "id": "vpc-03d4fae1af7ddbe72",
132 | "instance_tenancy": "default",
133 | "ipv4_ipam_pool_id": null,
134 | "ipv4_netmask_length": null,
135 | "ipv6_association_id": "",
136 | "ipv6_cidr_block": "",
137 | "ipv6_cidr_block_network_border_group": "",
138 | "ipv6_ipam_pool_id": "",
139 | "ipv6_netmask_length": 0,
140 | "main_route_table_id": "rtb-000f91dc68252e8d5",
141 | "owner_id": "123456789123",
142 | "tags": null,
143 | "tags_all": {}
144 | },
145 | "after": {
146 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
147 | "assign_generated_ipv6_cidr_block": false,
148 | "cidr_block": "10.0.0.0/16",
149 | "default_network_acl_id": "acl-00ff509137be0c29b",
150 | "default_route_table_id": "rtb-000f91dc68252e8d5",
151 | "default_security_group_id": "sg-0a2b0e570b6328288",
152 | "dhcp_options_id": "dopt-6310d108",
153 | "enable_classiclink": false,
154 | "enable_classiclink_dns_support": false,
155 | "enable_dns_hostnames": false,
156 | "enable_dns_support": true,
157 | "id": "vpc-03d4fae1af7ddbe72",
158 | "instance_tenancy": "default",
159 | "ipv4_ipam_pool_id": null,
160 | "ipv4_netmask_length": null,
161 | "ipv6_association_id": "",
162 | "ipv6_cidr_block": "",
163 | "ipv6_cidr_block_network_border_group": "",
164 | "ipv6_ipam_pool_id": "",
165 | "ipv6_netmask_length": 0,
166 | "main_route_table_id": "rtb-000f91dc68252e8d5",
167 | "owner_id": "123456789123",
168 | "tags": {},
169 | "tags_all": {}
170 | },
171 | "before_sensitive": {
172 | "tags_all": {}
173 | },
174 | "after_sensitive": {
175 | "tags": {},
176 | "tags_all": {}
177 | }
178 | }
179 | }],
180 | "resource_changes": [{
181 | "address": "aws_iam_policy.policy",
182 | "mode": "managed",
183 | "type": "aws_iam_policy",
184 | "name": "policy",
185 | "provider_name": "registry.terraform.io/hashicorp/aws",
186 | "change": {
187 | "actions": [
188 | "create"
189 | ],
190 | "before": null,
191 | "after": {
192 | "description": "My test policy",
193 | "name": "test_policy",
194 | "name_prefix": null,
195 | "path": "/",
196 | "policy": "{\"Statement\":[{\"Action\":[\"ec2:Describe*\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}],\"Version\":\"2012-10-17\"}",
197 | "tags": null
198 | },
199 | "after_unknown": {
200 | "arn": true,
201 | "id": true,
202 | "policy_id": true,
203 | "tags_all": true
204 | },
205 | "before_sensitive": false,
206 | "after_sensitive": {
207 | "tags_all": {}
208 | }
209 | }
210 | },
211 | {
212 | "address": "aws_s3_bucket.b",
213 | "mode": "managed",
214 | "type": "aws_s3_bucket",
215 | "name": "b",
216 | "provider_name": "registry.terraform.io/hashicorp/aws",
217 | "change": {
218 | "actions": [
219 | "create"
220 | ],
221 | "before": null,
222 | "after": {
223 | "acl": "private",
224 | "bucket": "my-tf-test-bucket",
225 | "bucket_prefix": null,
226 | "cors_rule": [],
227 | "force_destroy": false,
228 | "grant": [],
229 | "lifecycle_rule": [],
230 | "logging": [],
231 | "policy": null,
232 | "replication_configuration": [],
233 | "server_side_encryption_configuration": [],
234 | "tags": {
235 | "Environment": "Dev",
236 | "Name": "My bucket"
237 | },
238 | "tags_all": {
239 | "Environment": "Dev",
240 | "Name": "My bucket"
241 | },
242 | "website": []
243 | },
244 | "after_unknown": {
245 | "acceleration_status": true,
246 | "arn": true,
247 | "bucket_domain_name": true,
248 | "bucket_regional_domain_name": true,
249 | "cors_rule": [],
250 | "grant": [],
251 | "hosted_zone_id": true,
252 | "id": true,
253 | "lifecycle_rule": [],
254 | "logging": [],
255 | "object_lock_configuration": true,
256 | "object_lock_enabled": true,
257 | "region": true,
258 | "replication_configuration": [],
259 | "request_payer": true,
260 | "server_side_encryption_configuration": [],
261 | "tags": {},
262 | "tags_all": {},
263 | "versioning": true,
264 | "website": [],
265 | "website_domain": true,
266 | "website_endpoint": true
267 | },
268 | "before_sensitive": false,
269 | "after_sensitive": {
270 | "cors_rule": [],
271 | "grant": [],
272 | "lifecycle_rule": [],
273 | "logging": [],
274 | "object_lock_configuration": [],
275 | "replication_configuration": [],
276 | "server_side_encryption_configuration": [],
277 | "tags": {},
278 | "tags_all": {},
279 | "versioning": [],
280 | "website": []
281 | }
282 | }
283 | },
284 | {
285 | "address": "aws_vpc.example",
286 | "mode": "managed",
287 | "type": "aws_vpc",
288 | "name": "example",
289 | "provider_name": "registry.terraform.io/hashicorp/aws",
290 | "change": {
291 | "actions": [
292 | "no-op"
293 | ],
294 | "before": {
295 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
296 | "assign_generated_ipv6_cidr_block": false,
297 | "cidr_block": "10.0.0.0/16",
298 | "default_network_acl_id": "acl-00ff509137be0c29b",
299 | "default_route_table_id": "rtb-000f91dc68252e8d5",
300 | "default_security_group_id": "sg-0a2b0e570b6328288",
301 | "dhcp_options_id": "dopt-6310d108",
302 | "enable_classiclink": false,
303 | "enable_classiclink_dns_support": false,
304 | "enable_dns_hostnames": false,
305 | "enable_dns_support": true,
306 | "id": "vpc-03d4fae1af7ddbe72",
307 | "instance_tenancy": "default",
308 | "ipv4_ipam_pool_id": null,
309 | "ipv4_netmask_length": null,
310 | "ipv6_association_id": "",
311 | "ipv6_cidr_block": "",
312 | "ipv6_cidr_block_network_border_group": "",
313 | "ipv6_ipam_pool_id": "",
314 | "ipv6_netmask_length": 0,
315 | "main_route_table_id": "rtb-000f91dc68252e8d5",
316 | "owner_id": "123456789123",
317 | "tags": {},
318 | "tags_all": {}
319 | },
320 | "after": {
321 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
322 | "assign_generated_ipv6_cidr_block": false,
323 | "cidr_block": "10.0.0.0/16",
324 | "default_network_acl_id": "acl-00ff509137be0c29b",
325 | "default_route_table_id": "rtb-000f91dc68252e8d5",
326 | "default_security_group_id": "sg-0a2b0e570b6328288",
327 | "dhcp_options_id": "dopt-6310d108",
328 | "enable_classiclink": false,
329 | "enable_classiclink_dns_support": false,
330 | "enable_dns_hostnames": false,
331 | "enable_dns_support": true,
332 | "id": "vpc-03d4fae1af7ddbe72",
333 | "instance_tenancy": "default",
334 | "ipv4_ipam_pool_id": null,
335 | "ipv4_netmask_length": null,
336 | "ipv6_association_id": "",
337 | "ipv6_cidr_block": "",
338 | "ipv6_cidr_block_network_border_group": "",
339 | "ipv6_ipam_pool_id": "",
340 | "ipv6_netmask_length": 0,
341 | "main_route_table_id": "rtb-000f91dc68252e8d5",
342 | "owner_id": "123456789123",
343 | "tags": {},
344 | "tags_all": {}
345 | },
346 | "after_unknown": {},
347 | "before_sensitive": {
348 | "tags": {},
349 | "tags_all": {}
350 | },
351 | "after_sensitive": {
352 | "tags": {},
353 | "tags_all": {}
354 | }
355 | }
356 | }
357 | ],
358 | "prior_state": {
359 | "format_version": "0.2",
360 | "terraform_version": "1.0.2",
361 | "values": {
362 | "root_module": {
363 | "resources": [{
364 | "address": "aws_vpc.example",
365 | "mode": "managed",
366 | "type": "aws_vpc",
367 | "name": "example",
368 | "provider_name": "registry.terraform.io/hashicorp/aws",
369 | "schema_version": 1,
370 | "values": {
371 | "arn": "arn:aws:ec2:us-east-2:123456789123:vpc/vpc-03d4fae1af7ddbe72",
372 | "assign_generated_ipv6_cidr_block": false,
373 | "cidr_block": "10.0.0.0/16",
374 | "default_network_acl_id": "acl-00ff509137be0c29b",
375 | "default_route_table_id": "rtb-000f91dc68252e8d5",
376 | "default_security_group_id": "sg-0a2b0e570b6328288",
377 | "dhcp_options_id": "dopt-6310d108",
378 | "enable_classiclink": false,
379 | "enable_classiclink_dns_support": false,
380 | "enable_dns_hostnames": false,
381 | "enable_dns_support": true,
382 | "id": "vpc-03d4fae1af7ddbe72",
383 | "instance_tenancy": "default",
384 | "ipv4_ipam_pool_id": null,
385 | "ipv4_netmask_length": null,
386 | "ipv6_association_id": "",
387 | "ipv6_cidr_block": "",
388 | "ipv6_cidr_block_network_border_group": "",
389 | "ipv6_ipam_pool_id": "",
390 | "ipv6_netmask_length": 0,
391 | "main_route_table_id": "rtb-000f91dc68252e8d5",
392 | "owner_id": "123456789123",
393 | "tags": {},
394 | "tags_all": {}
395 | },
396 | "sensitive_values": {
397 | "tags": {},
398 | "tags_all": {}
399 | }
400 | }]
401 | }
402 | }
403 | },
404 | "configuration": {
405 | "provider_config": {
406 | "aws": {
407 | "name": "aws",
408 | "version_constraint": "~> 3.0",
409 | "expressions": {
410 | "region": {
411 | "constant_value": "us-east-2"
412 | }
413 | }
414 | }
415 | },
416 | "root_module": {
417 | "resources": [{
418 | "address": "aws_iam_policy.policy",
419 | "mode": "managed",
420 | "type": "aws_iam_policy",
421 | "name": "policy",
422 | "provider_config_key": "aws",
423 | "expressions": {
424 | "description": {
425 | "constant_value": "My test policy"
426 | },
427 | "name": {
428 | "constant_value": "test_policy"
429 | },
430 | "path": {
431 | "constant_value": "/"
432 | },
433 | "policy": {}
434 | },
435 | "schema_version": 0
436 | },
437 | {
438 | "address": "aws_s3_bucket.b",
439 | "mode": "managed",
440 | "type": "aws_s3_bucket",
441 | "name": "b",
442 | "provider_config_key": "aws",
443 | "expressions": {
444 | "bucket": {
445 | "constant_value": "my-tf-test-bucket"
446 | },
447 | "tags": {
448 | "constant_value": {
449 | "Environment": "Dev",
450 | "Name": "My bucket"
451 | }
452 | }
453 | },
454 | "schema_version": 0
455 | },
456 | {
457 | "address": "aws_vpc.example",
458 | "mode": "managed",
459 | "type": "aws_vpc",
460 | "name": "example",
461 | "provider_config_key": "aws",
462 | "expressions": {
463 | "cidr_block": {
464 | "constant_value": "10.0.0.0/16"
465 | }
466 | },
467 | "schema_version": 1
468 | }
469 | ]
470 | }
471 | }
472 | }
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/mock-tfconfig.sentinel:
--------------------------------------------------------------------------------
1 | import "strings"
2 | import "types"
3 |
4 | _modules = {
5 | "root": {
6 | "data": {
7 | "aws_ami": {
8 | "amazon-linux-2": {
9 | "config": {
10 | "filter": [
11 | {
12 | "name": "owner-alias",
13 | "values": [
14 | "amazon",
15 | ],
16 | },
17 | {
18 | "name": "name",
19 | "values": [
20 | "amzn2-ami-hvm-*-x86_64-ebs",
21 | ],
22 | },
23 | ],
24 | "most_recent": true,
25 | "owners": [
26 | "amazon",
27 | ],
28 | },
29 | "provisioners": null,
30 | "references": {
31 | "filter": [
32 | {
33 | "name": [],
34 | "values": [],
35 | },
36 | {
37 | "name": [],
38 | "values": [],
39 | },
40 | ],
41 | "most_recent": [],
42 | "owners": [],
43 | },
44 | },
45 | },
46 | "aws_caller_identity": {
47 | "current": {
48 | "config": {},
49 | "provisioners": null,
50 | "references": {},
51 | },
52 | },
53 | "aws_iam_policy_document": {
54 | "iam_policy_eks": {
55 | "config": {
56 | "statement": [
57 | {
58 | "actions": [
59 | "sts:AssumeRole",
60 | ],
61 | "effect": "Allow",
62 | "principals": [
63 | {
64 | "identifiers": [
65 | "eks.amazonaws.com",
66 | ],
67 | "type": "Service",
68 | },
69 | ],
70 | },
71 | ],
72 | },
73 | "provisioners": null,
74 | "references": {
75 | "statement": [
76 | {
77 | "actions": [],
78 | "effect": [],
79 | "principals": [
80 | {
81 | "identifiers": [],
82 | "type": [],
83 | },
84 | ],
85 | },
86 | ],
87 | },
88 | },
89 | "policy": {
90 | "config": {
91 | "statement": [
92 | {
93 | "actions": [
94 | "es:*",
95 | ],
96 | "principals": [
97 | {
98 | "identifiers": [
99 | "*",
100 | ],
101 | "type": "AWS",
102 | },
103 | ],
104 | "resources": [
105 | "*",
106 | ],
107 | },
108 | ],
109 | },
110 | "provisioners": null,
111 | "references": {
112 | "statement": [
113 | {
114 | "actions": [],
115 | "principals": [
116 | {
117 | "identifiers": [],
118 | "type": [],
119 | },
120 | ],
121 | "resources": [],
122 | },
123 | ],
124 | },
125 | },
126 | },
127 | },
128 | "modules": {},
129 | "outputs": {
130 | "db_app_public_dns": {
131 | "depends_on": [],
132 | "description": "DB Public DNS name",
133 | "references": [
134 | "aws_instance.db_app",
135 | ],
136 | "sensitive": false,
137 | "value": undefined,
138 | },
139 | "db_endpoint": {
140 | "depends_on": [],
141 | "description": "DB Endpoint",
142 | "references": [
143 | "aws_db_instance.default",
144 | ],
145 | "sensitive": false,
146 | "value": undefined,
147 | },
148 | "ec2_public_dns": {
149 | "depends_on": [],
150 | "description": "Web Host Public DNS name",
151 | "references": [
152 | "aws_instance.web_host",
153 | ],
154 | "sensitive": false,
155 | "value": undefined,
156 | },
157 | "endpoint": {
158 | "depends_on": [],
159 | "description": "",
160 | "references": [
161 | "aws_eks_cluster.eks_cluster",
162 | ],
163 | "sensitive": false,
164 | "value": undefined,
165 | },
166 | "kubeconfig-certificate-authority-data": {
167 | "depends_on": [],
168 | "description": "",
169 | "references": [
170 | "aws_eks_cluster.eks_cluster",
171 | ],
172 | "sensitive": false,
173 | "value": undefined,
174 | },
175 | "public_subnet": {
176 | "depends_on": [],
177 | "description": "The ID of the Public subnet",
178 | "references": [
179 | "aws_subnet.web_subnet",
180 | ],
181 | "sensitive": false,
182 | "value": undefined,
183 | },
184 | "public_subnet2": {
185 | "depends_on": [],
186 | "description": "The ID of the Public subnet",
187 | "references": [
188 | "aws_subnet.web_subnet2",
189 | ],
190 | "sensitive": false,
191 | "value": undefined,
192 | },
193 | "secret": {
194 | "depends_on": [],
195 | "description": "",
196 | "references": [
197 | "aws_iam_access_key.user",
198 | ],
199 | "sensitive": false,
200 | "value": undefined,
201 | },
202 | "username": {
203 | "depends_on": [],
204 | "description": "",
205 | "references": [
206 | "aws_iam_user.user",
207 | ],
208 | "sensitive": false,
209 | "value": undefined,
210 | },
211 | "vpc_id": {
212 | "depends_on": [],
213 | "description": "The ID of the VPC",
214 | "references": [
215 | "aws_vpc.web_vpc",
216 | ],
217 | "sensitive": false,
218 | "value": undefined,
219 | },
220 | },
221 | "providers": {
222 | "aws": {
223 | "alias": {
224 | "": {
225 | "config": {
226 | "region": "us-west-1",
227 | },
228 | "references": {
229 | "profile": [
230 | "var.profile",
231 | ],
232 | "region": [],
233 | },
234 | "version": "",
235 | },
236 | "plain_text_access_keys_provider": {
237 | "config": {
238 | "access_key": "{{REDACTED}}",
239 | "region": "us-west-1",
240 | "secret_key": "{{REDACTED}}",
241 | },
242 | "references": {
243 | "access_key": [],
244 | "region": [],
245 | "secret_key": [],
246 | },
247 | "version": "",
248 | },
249 | },
250 | "config": {
251 | "region": "us-west-1",
252 | },
253 | "references": {
254 | "profile": [
255 | "var.profile",
256 | ],
257 | "region": [],
258 | },
259 | "version": "",
260 | },
261 | },
262 | "resources": {
263 | "aws_db_instance": {
264 | "default": {
265 | "config": {
266 | "allocated_storage": "20",
267 | "apply_immediately": true,
268 | "backup_retention_period": 0,
269 | "engine": "mysql",
270 | "engine_version": "8.0",
271 | "instance_class": "db.t3.micro",
272 | "monitoring_interval": 0,
273 | "multi_az": false,
274 | "publicly_accessible": true,
275 | "skip_final_snapshot": true,
276 | "storage_encrypted": false,
277 | "username": "admin",
278 | },
279 | "provisioners": null,
280 | "references": {
281 | "allocated_storage": [],
282 | "apply_immediately": [],
283 | "backup_retention_period": [],
284 | "db_subnet_group_name": [
285 | "aws_db_subnet_group.default",
286 | ],
287 | "engine": [],
288 | "engine_version": [],
289 | "identifier": [
290 | "local.resource_prefix",
291 | ],
292 | "instance_class": [],
293 | "monitoring_interval": [],
294 | "multi_az": [],
295 | "name": [
296 | "var.dbname",
297 | ],
298 | "option_group_name": [
299 | "aws_db_option_group.default",
300 | ],
301 | "parameter_group_name": [
302 | "aws_db_parameter_group.default",
303 | ],
304 | "password": [
305 | "var.password",
306 | ],
307 | "publicly_accessible": [],
308 | "skip_final_snapshot": [],
309 | "storage_encrypted": [],
310 | "tags": [
311 | "local.resource_prefix",
312 | "local.resource_prefix",
313 | ],
314 | "username": [],
315 | "vpc_security_group_ids": [
316 | "aws_security_group.default",
317 | ],
318 | },
319 | },
320 | },
321 | "aws_db_option_group": {
322 | "default": {
323 | "config": {
324 | "engine_name": "mysql",
325 | "major_engine_version": "8.0",
326 | "option_group_description": "Terraform OG",
327 | },
328 | "provisioners": null,
329 | "references": {
330 | "engine_name": [],
331 | "major_engine_version": [],
332 | "name": [
333 | "local.resource_prefix",
334 | ],
335 | "option_group_description": [],
336 | "tags": [
337 | "local.resource_prefix",
338 | "local.resource_prefix",
339 | ],
340 | },
341 | },
342 | },
343 | "aws_db_parameter_group": {
344 | "default": {
345 | "config": {
346 | "description": "Terraform PG",
347 | "family": "mysql8.0",
348 | "parameter": [
349 | {
350 | "apply_method": "immediate",
351 | "name": "character_set_client",
352 | "value": "utf8",
353 | },
354 | {
355 | "apply_method": "immediate",
356 | "name": "character_set_server",
357 | "value": "utf8",
358 | },
359 | ],
360 | },
361 | "provisioners": null,
362 | "references": {
363 | "description": [],
364 | "family": [],
365 | "name": [
366 | "local.resource_prefix",
367 | ],
368 | "parameter": [
369 | {
370 | "apply_method": [],
371 | "name": [],
372 | "value": [],
373 | },
374 | {
375 | "apply_method": [],
376 | "name": [],
377 | "value": [],
378 | },
379 | ],
380 | "tags": [
381 | "local.resource_prefix",
382 | "local.resource_prefix",
383 | ],
384 | },
385 | },
386 | },
387 | "aws_db_subnet_group": {
388 | "default": {
389 | "config": {
390 | "description": "Terraform DB Subnet Group",
391 | },
392 | "provisioners": null,
393 | "references": {
394 | "description": [],
395 | "name": [
396 | "local.resource_prefix",
397 | ],
398 | "subnet_ids": [
399 | "aws_subnet.web_subnet",
400 | "aws_subnet.web_subnet2",
401 | ],
402 | "tags": [
403 | "local.resource_prefix",
404 | "local.resource_prefix",
405 | ],
406 | },
407 | },
408 | },
409 | "aws_ebs_snapshot": {
410 | "example_snapshot": {
411 | "config": {},
412 | "provisioners": null,
413 | "references": {
414 | "description": [
415 | "local.resource_prefix",
416 | ],
417 | "tags": [
418 | "local.resource_prefix",
419 | ],
420 | "volume_id": [
421 | "aws_ebs_volume.web_host_storage",
422 | ],
423 | },
424 | },
425 | },
426 | "aws_ebs_volume": {
427 | "web_host_storage": {
428 | "config": {
429 | "size": 1,
430 | },
431 | "provisioners": null,
432 | "references": {
433 | "availability_zone": [
434 | "var.availability_zone",
435 | ],
436 | "size": [],
437 | "tags": [
438 | "local.resource_prefix",
439 | ],
440 | },
441 | },
442 | },
443 | "aws_ecr_repository": {
444 | "repository": {
445 | "config": {
446 | "image_tag_mutability": "MUTABLE",
447 | },
448 | "provisioners": null,
449 | "references": {
450 | "image_tag_mutability": [],
451 | "name": [
452 | "local.resource_prefix",
453 | ],
454 | "tags": [
455 | "local.resource_prefix",
456 | ],
457 | },
458 | },
459 | },
460 | "aws_eks_cluster": {
461 | "eks_cluster": {
462 | "config": {
463 | "vpc_config": [
464 | {
465 | "endpoint_private_access": true,
466 | },
467 | ],
468 | },
469 | "provisioners": null,
470 | "references": {
471 | "name": [
472 | "local.eks_name",
473 | ],
474 | "role_arn": [
475 | "aws_iam_role.iam_for_eks",
476 | ],
477 | "vpc_config": [
478 | {
479 | "endpoint_private_access": [],
480 | "subnet_ids": [
481 | "aws_subnet.eks_subnet1",
482 | "aws_subnet.eks_subnet2",
483 | ],
484 | },
485 | ],
486 | },
487 | },
488 | },
489 | "aws_elasticsearch_domain": {
490 | "monitoring-framework": {
491 | "config": {
492 | "cluster_config": [
493 | {
494 | "dedicated_master_count": 1,
495 | "dedicated_master_enabled": false,
496 | "dedicated_master_type": "m4.large.elasticsearch",
497 | "instance_count": 1,
498 | "instance_type": "t2.small.elasticsearch",
499 | },
500 | ],
501 | "ebs_options": [
502 | {
503 | "ebs_enabled": true,
504 | "volume_size": 30,
505 | },
506 | ],
507 | "elasticsearch_version": "2.3",
508 | },
509 | "provisioners": null,
510 | "references": {
511 | "cluster_config": [
512 | {
513 | "dedicated_master_count": [],
514 | "dedicated_master_enabled": [],
515 | "dedicated_master_type": [],
516 | "instance_count": [],
517 | "instance_type": [],
518 | },
519 | ],
520 | "domain_name": [
521 | "var.environment",
522 | ],
523 | "ebs_options": [
524 | {
525 | "ebs_enabled": [],
526 | "volume_size": [],
527 | },
528 | ],
529 | "elasticsearch_version": [],
530 | },
531 | },
532 | },
533 | "aws_elasticsearch_domain_policy": {
534 | "monitoring-framework-policy": {
535 | "config": {},
536 | "provisioners": null,
537 | "references": {
538 | "access_policies": [
539 | "data.aws_iam_policy_document.policy",
540 | ],
541 | "domain_name": [
542 | "aws_elasticsearch_domain.monitoring-framework",
543 | ],
544 | },
545 | },
546 | },
547 | "aws_elb": {
548 | "weblb": {
549 | "config": {
550 | "connection_draining": true,
551 | "connection_draining_timeout": 400,
552 | "cross_zone_load_balancing": true,
553 | "health_check": [
554 | {
555 | "healthy_threshold": 2,
556 | "interval": 30,
557 | "target": "HTTP:8000/",
558 | "timeout": 3,
559 | "unhealthy_threshold": 2,
560 | },
561 | ],
562 | "idle_timeout": 400,
563 | "listener": [
564 | {
565 | "instance_port": 8000,
566 | "instance_protocol": "http",
567 | "lb_port": 80,
568 | "lb_protocol": "http",
569 | },
570 | ],
571 | "name": "weblb-terraform-elb",
572 | "tags": {
573 | "Name": "foobar-terraform-elb",
574 | },
575 | },
576 | "provisioners": null,
577 | "references": {
578 | "connection_draining": [],
579 | "connection_draining_timeout": [],
580 | "cross_zone_load_balancing": [],
581 | "health_check": [
582 | {
583 | "healthy_threshold": [],
584 | "interval": [],
585 | "target": [],
586 | "timeout": [],
587 | "unhealthy_threshold": [],
588 | },
589 | ],
590 | "idle_timeout": [],
591 | "instances": [
592 | "aws_instance.web_host",
593 | ],
594 | "listener": [
595 | {
596 | "instance_port": [],
597 | "instance_protocol": [],
598 | "lb_port": [],
599 | "lb_protocol": [],
600 | },
601 | ],
602 | "name": [],
603 | "security_groups": [
604 | "aws_security_group.web-node",
605 | ],
606 | "subnets": [
607 | "aws_subnet.web_subnet",
608 | ],
609 | "tags": [],
610 | },
611 | },
612 | },
613 | "aws_flow_log": {
614 | "vpcflowlogs": {
615 | "config": {
616 | "log_destination_type": "s3",
617 | "traffic_type": "ALL",
618 | },
619 | "provisioners": null,
620 | "references": {
621 | "log_destination": [
622 | "aws_s3_bucket.flowbucket",
623 | ],
624 | "log_destination_type": [],
625 | "tags": [
626 | "local.resource_prefix",
627 | "local.resource_prefix",
628 | ],
629 | "traffic_type": [],
630 | "vpc_id": [
631 | "aws_vpc.web_vpc",
632 | ],
633 | },
634 | },
635 | },
636 | "aws_iam_access_key": {
637 | "user": {
638 | "config": {},
639 | "provisioners": null,
640 | "references": {
641 | "user": [
642 | "aws_iam_user.user",
643 | ],
644 | },
645 | },
646 | },
647 | "aws_iam_instance_profile": {
648 | "ec2profile": {
649 | "config": {},
650 | "provisioners": null,
651 | "references": {
652 | "name": [
653 | "local.resource_prefix",
654 | ],
655 | "role": [
656 | "aws_iam_role.ec2role",
657 | ],
658 | },
659 | },
660 | },
661 | "aws_iam_role": {
662 | "ec2role": {
663 | "config": {
664 | "assume_role_policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"ec2.amazonaws.com\"\n },\n \"Effect\": \"Allow\",\n \"Sid\": \"\"\n }\n ]\n}\n",
665 | "path": "/",
666 | },
667 | "provisioners": null,
668 | "references": {
669 | "assume_role_policy": [],
670 | "name": [
671 | "local.resource_prefix",
672 | ],
673 | "path": [],
674 | "tags": [
675 | "local.resource_prefix",
676 | "local.resource_prefix",
677 | ],
678 | },
679 | },
680 | "iam_for_eks": {
681 | "config": {},
682 | "provisioners": null,
683 | "references": {
684 | "assume_role_policy": [
685 | "data.aws_iam_policy_document.iam_policy_eks",
686 | ],
687 | "name": [
688 | "local.resource_prefix",
689 | ],
690 | },
691 | },
692 | "iam_for_lambda": {
693 | "config": {
694 | "assume_role_policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"lambda.amazonaws.com\"\n },\n \"Effect\": \"Allow\",\n \"Sid\": \"\"\n }\n ]\n}\n",
695 | },
696 | "provisioners": null,
697 | "references": {
698 | "assume_role_policy": [],
699 | "name": [
700 | "local.resource_prefix",
701 | ],
702 | },
703 | },
704 | },
705 | "aws_iam_role_policy": {
706 | "ec2policy": {
707 | "config": {
708 | "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"s3:*\",\n \"ec2:*\",\n \"rds:*\"\n ],\n \"Effect\": \"Allow\",\n \"Resource\": \"*\"\n }\n ]\n}\n",
709 | },
710 | "provisioners": null,
711 | "references": {
712 | "name": [
713 | "local.resource_prefix",
714 | ],
715 | "policy": [],
716 | "role": [
717 | "aws_iam_role.ec2role",
718 | ],
719 | },
720 | },
721 | },
722 | "aws_iam_role_policy_attachment": {
723 | "policy_attachment-AmazonEKSClusterPolicy": {
724 | "config": {
725 | "policy_arn": "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
726 | },
727 | "provisioners": null,
728 | "references": {
729 | "policy_arn": [],
730 | "role": [
731 | "aws_iam_role.iam_for_eks",
732 | ],
733 | },
734 | },
735 | "policy_attachment-AmazonEKSServicePolicy": {
736 | "config": {
737 | "policy_arn": "arn:aws:iam::aws:policy/AmazonEKSServicePolicy",
738 | },
739 | "provisioners": null,
740 | "references": {
741 | "policy_arn": [],
742 | "role": [
743 | "aws_iam_role.iam_for_eks",
744 | ],
745 | },
746 | },
747 | },
748 | "aws_iam_user": {
749 | "user": {
750 | "config": {
751 | "force_destroy": true,
752 | },
753 | "provisioners": null,
754 | "references": {
755 | "force_destroy": [],
756 | "name": [
757 | "local.resource_prefix",
758 | ],
759 | "tags": [
760 | "local.resource_prefix",
761 | "local.resource_prefix",
762 | ],
763 | },
764 | },
765 | },
766 | "aws_iam_user_policy": {
767 | "userpolicy": {
768 | "config": {
769 | "name": "excess_policy",
770 | "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"ec2:*\",\n \"s3:*\",\n \"lambda:*\",\n \"cloudwatch:*\"\n ],\n \"Effect\": \"Allow\",\n \"Resource\": \"*\"\n }\n ]\n}\n",
771 | },
772 | "provisioners": null,
773 | "references": {
774 | "name": [],
775 | "policy": [],
776 | "user": [
777 | "aws_iam_user.user",
778 | ],
779 | },
780 | },
781 | },
782 | "aws_instance": {
783 | "db_app": {
784 | "config": {
785 | "instance_type": "t2.nano",
786 | },
787 | "provisioners": null,
788 | "references": {
789 | "ami": [
790 | "data.aws_ami.amazon-linux-2",
791 | ],
792 | "iam_instance_profile": [
793 | "aws_iam_instance_profile.ec2profile",
794 | ],
795 | "instance_type": [],
796 | "subnet_id": [
797 | "aws_subnet.web_subnet",
798 | ],
799 | "tags": [
800 | "local.resource_prefix",
801 | ],
802 | "user_data": [
803 | "aws_db_instance.default",
804 | "aws_db_instance.default",
805 | "var.password",
806 | "aws_db_instance.default",
807 | ],
808 | "vpc_security_group_ids": [
809 | "aws_security_group.web-node",
810 | ],
811 | },
812 | },
813 | "web_host": {
814 | "config": {
815 | "instance_type": "t2.nano",
816 | "user_data": "#! /bin/bash\nsudo apt-get update\nsudo apt-get install -y apache2\nsudo systemctl start apache2\nsudo systemctl enable apache2\nexport AWS_ACCESS_KEY_ID={{REDACTED}}\nexport AWS_SECRET_ACCESS_KEY={{REDACTED}}\nexport AWS_DEFAULT_REGION=us-west-2\necho \"Deployed via Terraform
\" | sudo tee /var/www/html/index.html\n",
817 | },
818 | "provisioners": null,
819 | "references": {
820 | "ami": [
821 | "var.ami",
822 | ],
823 | "instance_type": [],
824 | "subnet_id": [
825 | "aws_subnet.web_subnet",
826 | ],
827 | "tags": [
828 | "local.resource_prefix",
829 | ],
830 | "user_data": [],
831 | "vpc_security_group_ids": [
832 | "aws_security_group.web-node",
833 | ],
834 | },
835 | },
836 | },
837 | "aws_internet_gateway": {
838 | "web_igw": {
839 | "config": {},
840 | "provisioners": null,
841 | "references": {
842 | "tags": [
843 | "local.resource_prefix",
844 | ],
845 | "vpc_id": [
846 | "aws_vpc.web_vpc",
847 | ],
848 | },
849 | },
850 | },
851 | "aws_kms_alias": {
852 | "logs_key_alias": {
853 | "config": {},
854 | "provisioners": null,
855 | "references": {
856 | "name": [
857 | "local.resource_prefix",
858 | ],
859 | "target_key_id": [
860 | "aws_kms_key.logs_key",
861 | ],
862 | },
863 | },
864 | },
865 | "aws_kms_key": {
866 | "logs_key": {
867 | "config": {
868 | "deletion_window_in_days": 7,
869 | },
870 | "provisioners": null,
871 | "references": {
872 | "deletion_window_in_days": [],
873 | "description": [
874 | "local.resource_prefix",
875 | ],
876 | },
877 | },
878 | },
879 | "aws_lambda_function": {
880 | "analysis_lambda": {
881 | "config": {
882 | "environment": [
883 | {
884 | "variables": {
885 | "access_key": "{{REDACTED}}",
886 | "secret_key": "{{REDACTED}}",
887 | },
888 | },
889 | ],
890 | "filename": "resources/lambda_function_payload.zip",
891 | "handler": "exports.test",
892 | "runtime": "nodejs12.x",
893 | "source_code_hash": null,
894 | },
895 | "provisioners": null,
896 | "references": {
897 | "environment": [
898 | {
899 | "variables": [],
900 | },
901 | ],
902 | "filename": [],
903 | "function_name": [
904 | "local.resource_prefix",
905 | ],
906 | "handler": [],
907 | "role": [
908 | "aws_iam_role.iam_for_lambda",
909 | ],
910 | "runtime": [],
911 | "source_code_hash": [],
912 | },
913 | },
914 | },
915 | "aws_neptune_cluster": {
916 | "default": {
917 | "config": {
918 | "apply_immediately": true,
919 | "backup_retention_period": 5,
920 | "engine": "neptune",
921 | "iam_database_authentication_enabled": false,
922 | "preferred_backup_window": "07:00-09:00",
923 | "skip_final_snapshot": true,
924 | "storage_encrypted": false,
925 | },
926 | "provisioners": null,
927 | "references": {
928 | "apply_immediately": [],
929 | "backup_retention_period": [],
930 | "cluster_identifier": [
931 | "var.neptune-dbname",
932 | ],
933 | "engine": [],
934 | "iam_database_authentication_enabled": [],
935 | "preferred_backup_window": [],
936 | "skip_final_snapshot": [],
937 | "storage_encrypted": [],
938 | },
939 | },
940 | },
941 | "aws_neptune_cluster_instance": {
942 | "default": {
943 | "config": {
944 | "apply_immediately": true,
945 | "engine": "neptune",
946 | "instance_class": "db.t3.medium",
947 | },
948 | "provisioners": null,
949 | "references": {
950 | "apply_immediately": [],
951 | "cluster_identifier": [
952 | "aws_neptune_cluster.default",
953 | ],
954 | "engine": [],
955 | "instance_class": [],
956 | },
957 | },
958 | },
959 | "aws_neptune_cluster_snapshot": {
960 | "default": {
961 | "config": {
962 | "db_cluster_snapshot_identifier": "resourcetestsnapshot1",
963 | },
964 | "provisioners": null,
965 | "references": {
966 | "db_cluster_identifier": [
967 | "aws_neptune_cluster.default",
968 | ],
969 | "db_cluster_snapshot_identifier": [],
970 | },
971 | },
972 | },
973 | "aws_network_interface": {
974 | "web-eni": {
975 | "config": {
976 | "private_ips": [
977 | "172.16.10.100",
978 | ],
979 | },
980 | "provisioners": null,
981 | "references": {
982 | "private_ips": [],
983 | "subnet_id": [
984 | "aws_subnet.web_subnet",
985 | ],
986 | "tags": [
987 | "local.resource_prefix",
988 | ],
989 | },
990 | },
991 | },
992 | "aws_route": {
993 | "public_internet_gateway": {
994 | "config": {
995 | "destination_cidr_block": "0.0.0.0/0",
996 | "timeouts": null,
997 | },
998 | "provisioners": null,
999 | "references": {
1000 | "destination_cidr_block": [],
1001 | "gateway_id": [
1002 | "aws_internet_gateway.web_igw",
1003 | ],
1004 | "route_table_id": [
1005 | "aws_route_table.web_rtb",
1006 | ],
1007 | "timeouts": [],
1008 | },
1009 | },
1010 | },
1011 | "aws_route_table": {
1012 | "web_rtb": {
1013 | "config": {},
1014 | "provisioners": null,
1015 | "references": {
1016 | "tags": [
1017 | "local.resource_prefix",
1018 | ],
1019 | "vpc_id": [
1020 | "aws_vpc.web_vpc",
1021 | ],
1022 | },
1023 | },
1024 | },
1025 | "aws_route_table_association": {
1026 | "rtbassoc": {
1027 | "config": {},
1028 | "provisioners": null,
1029 | "references": {
1030 | "route_table_id": [
1031 | "aws_route_table.web_rtb",
1032 | ],
1033 | "subnet_id": [
1034 | "aws_subnet.web_subnet",
1035 | ],
1036 | },
1037 | },
1038 | "rtbassoc2": {
1039 | "config": {},
1040 | "provisioners": null,
1041 | "references": {
1042 | "route_table_id": [
1043 | "aws_route_table.web_rtb",
1044 | ],
1045 | "subnet_id": [
1046 | "aws_subnet.web_subnet2",
1047 | ],
1048 | },
1049 | },
1050 | },
1051 | "aws_s3_bucket": {
1052 | "data": {
1053 | "config": {
1054 | "acl": "public-read",
1055 | "force_destroy": true,
1056 | },
1057 | "provisioners": null,
1058 | "references": {
1059 | "acl": [],
1060 | "bucket": [
1061 | "local.resource_prefix",
1062 | ],
1063 | "force_destroy": [],
1064 | "tags": [
1065 | "local.resource_prefix",
1066 | "local.resource_prefix",
1067 | ],
1068 | },
1069 | },
1070 | "data_science": {
1071 | "config": {
1072 | "acl": "private",
1073 | "force_destroy": true,
1074 | "logging": [
1075 | {
1076 | "target_prefix": "log/",
1077 | },
1078 | ],
1079 | "versioning": [
1080 | {
1081 | "enabled": true,
1082 | },
1083 | ],
1084 | },
1085 | "provisioners": null,
1086 | "references": {
1087 | "acl": [],
1088 | "bucket": [
1089 | "local.resource_prefix",
1090 | ],
1091 | "force_destroy": [],
1092 | "logging": [
1093 | {
1094 | "target_bucket": [
1095 | "aws_s3_bucket.logs",
1096 | ],
1097 | "target_prefix": [],
1098 | },
1099 | ],
1100 | "versioning": [
1101 | {
1102 | "enabled": [],
1103 | },
1104 | ],
1105 | },
1106 | },
1107 | "financials": {
1108 | "config": {
1109 | "acl": "private",
1110 | "force_destroy": true,
1111 | },
1112 | "provisioners": null,
1113 | "references": {
1114 | "acl": [],
1115 | "bucket": [
1116 | "local.resource_prefix",
1117 | ],
1118 | "force_destroy": [],
1119 | "tags": [
1120 | "local.resource_prefix",
1121 | "local.resource_prefix",
1122 | ],
1123 | },
1124 | },
1125 | "flowbucket": {
1126 | "config": {
1127 | "force_destroy": true,
1128 | },
1129 | "provisioners": null,
1130 | "references": {
1131 | "bucket": [
1132 | "local.resource_prefix",
1133 | ],
1134 | "force_destroy": [],
1135 | "tags": [
1136 | "local.resource_prefix",
1137 | "local.resource_prefix",
1138 | ],
1139 | },
1140 | },
1141 | "logs": {
1142 | "config": {
1143 | "acl": "log-delivery-write",
1144 | "force_destroy": true,
1145 | "server_side_encryption_configuration": [
1146 | {
1147 | "rule": [
1148 | {
1149 | "apply_server_side_encryption_by_default": [
1150 | {
1151 | "sse_algorithm": "aws:kms",
1152 | },
1153 | ],
1154 | },
1155 | ],
1156 | },
1157 | ],
1158 | "versioning": [
1159 | {
1160 | "enabled": true,
1161 | },
1162 | ],
1163 | },
1164 | "provisioners": null,
1165 | "references": {
1166 | "acl": [],
1167 | "bucket": [
1168 | "local.resource_prefix",
1169 | ],
1170 | "force_destroy": [],
1171 | "server_side_encryption_configuration": [
1172 | {
1173 | "rule": [
1174 | {
1175 | "apply_server_side_encryption_by_default": [
1176 | {
1177 | "kms_master_key_id": [
1178 | "aws_kms_key.logs_key",
1179 | ],
1180 | "sse_algorithm": [],
1181 | },
1182 | ],
1183 | },
1184 | ],
1185 | },
1186 | ],
1187 | "tags": [
1188 | "local.resource_prefix",
1189 | "local.resource_prefix",
1190 | ],
1191 | "versioning": [
1192 | {
1193 | "enabled": [],
1194 | },
1195 | ],
1196 | },
1197 | },
1198 | "operations": {
1199 | "config": {
1200 | "acl": "private",
1201 | "force_destroy": true,
1202 | "versioning": [
1203 | {
1204 | "enabled": true,
1205 | },
1206 | ],
1207 | },
1208 | "provisioners": null,
1209 | "references": {
1210 | "acl": [],
1211 | "bucket": [
1212 | "local.resource_prefix",
1213 | ],
1214 | "force_destroy": [],
1215 | "tags": [
1216 | "local.resource_prefix",
1217 | "local.resource_prefix",
1218 | ],
1219 | "versioning": [
1220 | {
1221 | "enabled": [],
1222 | },
1223 | ],
1224 | },
1225 | },
1226 | },
1227 | "aws_s3_bucket_object": {
1228 | "data_object": {
1229 | "config": {
1230 | "key": "customer-master.xlsx",
1231 | "source": "resources/customer-master.xlsx",
1232 | },
1233 | "provisioners": null,
1234 | "references": {
1235 | "bucket": [
1236 | "aws_s3_bucket.data",
1237 | ],
1238 | "key": [],
1239 | "source": [],
1240 | "tags": [
1241 | "local.resource_prefix",
1242 | "local.resource_prefix",
1243 | ],
1244 | },
1245 | },
1246 | },
1247 | "aws_security_group": {
1248 | "default": {
1249 | "config": {},
1250 | "provisioners": null,
1251 | "references": {
1252 | "name": [
1253 | "local.resource_prefix",
1254 | ],
1255 | "tags": [
1256 | "local.resource_prefix",
1257 | "local.resource_prefix",
1258 | ],
1259 | "vpc_id": [
1260 | "aws_vpc.web_vpc",
1261 | ],
1262 | },
1263 | },
1264 | "web-node": {
1265 | "config": {},
1266 | "provisioners": null,
1267 | "references": {
1268 | "description": [
1269 | "local.resource_prefix",
1270 | ],
1271 | "name": [
1272 | "local.resource_prefix",
1273 | ],
1274 | "vpc_id": [
1275 | "aws_vpc.web_vpc",
1276 | ],
1277 | },
1278 | },
1279 | },
1280 | "aws_security_group_rule": {
1281 | "egress": {
1282 | "config": {
1283 | "cidr_blocks": [
1284 | "0.0.0.0/0",
1285 | ],
1286 | "from_port": 0,
1287 | "protocol": "-1",
1288 | "to_port": 0,
1289 | "type": "egress",
1290 | },
1291 | "provisioners": null,
1292 | "references": {
1293 | "cidr_blocks": [],
1294 | "from_port": [],
1295 | "protocol": [],
1296 | "security_group_id": [
1297 | "aws_security_group.default",
1298 | ],
1299 | "to_port": [],
1300 | "type": [],
1301 | },
1302 | },
1303 | "ingress": {
1304 | "config": {
1305 | "from_port": "3306",
1306 | "protocol": "tcp",
1307 | "to_port": "3306",
1308 | "type": "ingress",
1309 | },
1310 | "provisioners": null,
1311 | "references": {
1312 | "cidr_blocks": [
1313 | "aws_vpc.web_vpc",
1314 | ],
1315 | "from_port": [],
1316 | "protocol": [],
1317 | "security_group_id": [
1318 | "aws_security_group.default",
1319 | ],
1320 | "to_port": [],
1321 | "type": [],
1322 | },
1323 | },
1324 | },
1325 | "aws_subnet": {
1326 | "eks_subnet1": {
1327 | "config": {
1328 | "cidr_block": "10.10.10.0/24",
1329 | "map_public_ip_on_launch": true,
1330 | },
1331 | "provisioners": null,
1332 | "references": {
1333 | "availability_zone": [
1334 | "var.availability_zone",
1335 | ],
1336 | "cidr_block": [],
1337 | "map_public_ip_on_launch": [],
1338 | "tags": [
1339 | "local.resource_prefix",
1340 | "local.eks_name",
1341 | ],
1342 | "vpc_id": [
1343 | "aws_vpc.eks_vpc",
1344 | ],
1345 | },
1346 | },
1347 | "eks_subnet2": {
1348 | "config": {
1349 | "cidr_block": "10.10.11.0/24",
1350 | "map_public_ip_on_launch": true,
1351 | },
1352 | "provisioners": null,
1353 | "references": {
1354 | "availability_zone": [
1355 | "var.availability_zone2",
1356 | ],
1357 | "cidr_block": [],
1358 | "map_public_ip_on_launch": [],
1359 | "tags": [
1360 | "local.resource_prefix",
1361 | "local.eks_name",
1362 | ],
1363 | "vpc_id": [
1364 | "aws_vpc.eks_vpc",
1365 | ],
1366 | },
1367 | },
1368 | "web_subnet": {
1369 | "config": {
1370 | "cidr_block": "172.16.10.0/24",
1371 | "map_public_ip_on_launch": true,
1372 | },
1373 | "provisioners": null,
1374 | "references": {
1375 | "availability_zone": [
1376 | "var.availability_zone",
1377 | ],
1378 | "cidr_block": [],
1379 | "map_public_ip_on_launch": [],
1380 | "tags": [
1381 | "local.resource_prefix",
1382 | ],
1383 | "vpc_id": [
1384 | "aws_vpc.web_vpc",
1385 | ],
1386 | },
1387 | },
1388 | "web_subnet2": {
1389 | "config": {
1390 | "cidr_block": "172.16.11.0/24",
1391 | "map_public_ip_on_launch": true,
1392 | },
1393 | "provisioners": null,
1394 | "references": {
1395 | "availability_zone": [
1396 | "var.availability_zone2",
1397 | ],
1398 | "cidr_block": [],
1399 | "map_public_ip_on_launch": [],
1400 | "tags": [
1401 | "local.resource_prefix",
1402 | ],
1403 | "vpc_id": [
1404 | "aws_vpc.web_vpc",
1405 | ],
1406 | },
1407 | },
1408 | },
1409 | "aws_volume_attachment": {
1410 | "ebs_att": {
1411 | "config": {
1412 | "device_name": "/dev/sdh",
1413 | },
1414 | "provisioners": null,
1415 | "references": {
1416 | "device_name": [],
1417 | "instance_id": [
1418 | "aws_instance.web_host",
1419 | ],
1420 | "volume_id": [
1421 | "aws_ebs_volume.web_host_storage",
1422 | ],
1423 | },
1424 | },
1425 | },
1426 | "aws_vpc": {
1427 | "eks_vpc": {
1428 | "config": {
1429 | "cidr_block": "10.10.0.0/16",
1430 | "enable_dns_hostnames": true,
1431 | "enable_dns_support": true,
1432 | },
1433 | "provisioners": null,
1434 | "references": {
1435 | "cidr_block": [],
1436 | "enable_dns_hostnames": [],
1437 | "enable_dns_support": [],
1438 | "tags": [
1439 | "local.resource_prefix",
1440 | ],
1441 | },
1442 | },
1443 | "web_vpc": {
1444 | "config": {
1445 | "cidr_block": "172.16.0.0/16",
1446 | "enable_dns_hostnames": true,
1447 | "enable_dns_support": true,
1448 | },
1449 | "provisioners": null,
1450 | "references": {
1451 | "cidr_block": [],
1452 | "enable_dns_hostnames": [],
1453 | "enable_dns_support": [],
1454 | "tags": [
1455 | "local.resource_prefix",
1456 | ],
1457 | },
1458 | },
1459 | },
1460 | "null_resource": {
1461 | "push_image": {
1462 | "config": {},
1463 | "provisioners": [
1464 | {
1465 | "config": {},
1466 | "references": {
1467 | "command": [
1468 | "var.region",
1469 | "data.aws_caller_identity.current",
1470 | "var.region",
1471 | "aws_ecr_repository.repository",
1472 | "aws_ecr_repository.repository",
1473 | "local.docker_image",
1474 | "local.docker_image",
1475 | ],
1476 | "working_dir": [
1477 | "path.module",
1478 | ],
1479 | },
1480 | "type": "local-exec",
1481 | },
1482 | ],
1483 | "references": {},
1484 | },
1485 | },
1486 | },
1487 | "variables": {
1488 | "ami": {
1489 | "default": "ami-09a5b0b7edf08843d",
1490 | "description": "",
1491 | },
1492 | "availability_zone": {
1493 | "default": "us-west-2a",
1494 | "description": "",
1495 | },
1496 | "availability_zone2": {
1497 | "default": "us-west-2b",
1498 | "description": "",
1499 | },
1500 | "company_name": {
1501 | "default": "acme",
1502 | "description": "",
1503 | },
1504 | "dbname": {
1505 | "default": "db1",
1506 | "description": "Name of the Database",
1507 | },
1508 | "environment": {
1509 | "default": "dev",
1510 | "description": "",
1511 | },
1512 | "neptune-dbname": {
1513 | "default": "neptunedb1",
1514 | "description": "Name of the Neptune graph database",
1515 | },
1516 | "password": {
1517 | "default": "Aa1234321Bb",
1518 | "description": "Database password",
1519 | },
1520 | "profile": {
1521 | "default": "default",
1522 | "description": "",
1523 | },
1524 | "region": {
1525 | "default": "us-west-2",
1526 | "description": "",
1527 | },
1528 | },
1529 | },
1530 | }
1531 |
1532 | module_paths = [
1533 | [],
1534 | ]
1535 |
1536 | module = func(path) {
1537 | if types.type_of(path) is not "list" {
1538 | error("expected list, got", types.type_of(path))
1539 | }
1540 |
1541 | if length(path) < 1 {
1542 | return _modules.root
1543 | }
1544 |
1545 | addr = []
1546 | for path as p {
1547 | append(addr, "module")
1548 | append(addr, p)
1549 | }
1550 |
1551 | return _modules[strings.join(addr, ".")]
1552 | }
1553 |
1554 | data = _modules.root.data
1555 | modules = _modules.root.modules
1556 | providers = _modules.root.providers
1557 | resources = _modules.root.resources
1558 | variables = _modules.root.variables
1559 | outputs = _modules.root.outputs
1560 |
--------------------------------------------------------------------------------
/sample-data/terraform-terragoat-aws-tfstate-sentinel-mocks/mock-tfconfig-v2.sentinel:
--------------------------------------------------------------------------------
1 | import "strings"
2 |
3 | providers = {
4 | "aws": {
5 | "alias": "",
6 | "config": {
7 | "profile": {
8 | "references": [
9 | "var.profile",
10 | ],
11 | },
12 | "region": {
13 | "constant_value": "us-west-1",
14 | },
15 | },
16 | "module_address": "",
17 | "name": "aws",
18 | "provider_config_key": "aws",
19 | "version_constraint": "",
20 | },
21 | "aws.plain_text_access_keys_provider": {
22 | "alias": "plain_text_access_keys_provider",
23 | "config": {
24 | "access_key": {
25 | "constant_value": "{{REDACTED}}",
26 | },
27 | "region": {
28 | "constant_value": "us-west-1",
29 | },
30 | "secret_key": {
31 | "constant_value": "{{REDACTED}}",
32 | },
33 | },
34 | "module_address": "",
35 | "name": "aws",
36 | "provider_config_key": "aws.plain_text_access_keys_provider",
37 | "version_constraint": "",
38 | },
39 | }
40 |
41 | resources = {
42 | "aws_db_instance.default": {
43 | "address": "aws_db_instance.default",
44 | "config": {
45 | "allocated_storage": {
46 | "constant_value": "20",
47 | },
48 | "apply_immediately": {
49 | "constant_value": true,
50 | },
51 | "backup_retention_period": {
52 | "constant_value": 0,
53 | },
54 | "db_subnet_group_name": {
55 | "references": [
56 | "aws_db_subnet_group.default",
57 | ],
58 | },
59 | "engine": {
60 | "constant_value": "mysql",
61 | },
62 | "engine_version": {
63 | "constant_value": "8.0",
64 | },
65 | "identifier": {
66 | "references": [
67 | "local.resource_prefix",
68 | ],
69 | },
70 | "instance_class": {
71 | "constant_value": "db.t3.micro",
72 | },
73 | "monitoring_interval": {
74 | "constant_value": 0,
75 | },
76 | "multi_az": {
77 | "constant_value": false,
78 | },
79 | "name": {
80 | "references": [
81 | "var.dbname",
82 | ],
83 | },
84 | "option_group_name": {
85 | "references": [
86 | "aws_db_option_group.default",
87 | ],
88 | },
89 | "parameter_group_name": {
90 | "references": [
91 | "aws_db_parameter_group.default",
92 | ],
93 | },
94 | "password": {
95 | "references": [
96 | "var.password",
97 | ],
98 | },
99 | "publicly_accessible": {
100 | "constant_value": true,
101 | },
102 | "skip_final_snapshot": {
103 | "constant_value": true,
104 | },
105 | "storage_encrypted": {
106 | "constant_value": false,
107 | },
108 | "tags": {
109 | "references": [
110 | "local.resource_prefix",
111 | "local.resource_prefix",
112 | ],
113 | },
114 | "username": {
115 | "constant_value": "admin",
116 | },
117 | "vpc_security_group_ids": {
118 | "references": [
119 | "aws_security_group.default",
120 | ],
121 | },
122 | },
123 | "count": {},
124 | "depends_on": [],
125 | "for_each": {},
126 | "mode": "managed",
127 | "module_address": "",
128 | "name": "default",
129 | "provider_config_key": "aws",
130 | "provisioners": [],
131 | "type": "aws_db_instance",
132 | },
133 | "aws_db_option_group.default": {
134 | "address": "aws_db_option_group.default",
135 | "config": {
136 | "engine_name": {
137 | "constant_value": "mysql",
138 | },
139 | "major_engine_version": {
140 | "constant_value": "8.0",
141 | },
142 | "name": {
143 | "references": [
144 | "local.resource_prefix",
145 | ],
146 | },
147 | "option_group_description": {
148 | "constant_value": "Terraform OG",
149 | },
150 | "tags": {
151 | "references": [
152 | "local.resource_prefix",
153 | "local.resource_prefix",
154 | ],
155 | },
156 | },
157 | "count": {},
158 | "depends_on": [],
159 | "for_each": {},
160 | "mode": "managed",
161 | "module_address": "",
162 | "name": "default",
163 | "provider_config_key": "aws",
164 | "provisioners": [],
165 | "type": "aws_db_option_group",
166 | },
167 | "aws_db_parameter_group.default": {
168 | "address": "aws_db_parameter_group.default",
169 | "config": {
170 | "description": {
171 | "constant_value": "Terraform PG",
172 | },
173 | "family": {
174 | "constant_value": "mysql8.0",
175 | },
176 | "name": {
177 | "references": [
178 | "local.resource_prefix",
179 | ],
180 | },
181 | "parameter": [
182 | {
183 | "apply_method": {
184 | "constant_value": "immediate",
185 | },
186 | "name": {
187 | "constant_value": "character_set_client",
188 | },
189 | "value": {
190 | "constant_value": "utf8",
191 | },
192 | },
193 | {
194 | "apply_method": {
195 | "constant_value": "immediate",
196 | },
197 | "name": {
198 | "constant_value": "character_set_server",
199 | },
200 | "value": {
201 | "constant_value": "utf8",
202 | },
203 | },
204 | ],
205 | "tags": {
206 | "references": [
207 | "local.resource_prefix",
208 | "local.resource_prefix",
209 | ],
210 | },
211 | },
212 | "count": {},
213 | "depends_on": [],
214 | "for_each": {},
215 | "mode": "managed",
216 | "module_address": "",
217 | "name": "default",
218 | "provider_config_key": "aws",
219 | "provisioners": [],
220 | "type": "aws_db_parameter_group",
221 | },
222 | "aws_db_subnet_group.default": {
223 | "address": "aws_db_subnet_group.default",
224 | "config": {
225 | "description": {
226 | "constant_value": "Terraform DB Subnet Group",
227 | },
228 | "name": {
229 | "references": [
230 | "local.resource_prefix",
231 | ],
232 | },
233 | "subnet_ids": {
234 | "references": [
235 | "aws_subnet.web_subnet",
236 | "aws_subnet.web_subnet2",
237 | ],
238 | },
239 | "tags": {
240 | "references": [
241 | "local.resource_prefix",
242 | "local.resource_prefix",
243 | ],
244 | },
245 | },
246 | "count": {},
247 | "depends_on": [],
248 | "for_each": {},
249 | "mode": "managed",
250 | "module_address": "",
251 | "name": "default",
252 | "provider_config_key": "aws",
253 | "provisioners": [],
254 | "type": "aws_db_subnet_group",
255 | },
256 | "aws_ebs_snapshot.example_snapshot": {
257 | "address": "aws_ebs_snapshot.example_snapshot",
258 | "config": {
259 | "description": {
260 | "references": [
261 | "local.resource_prefix",
262 | ],
263 | },
264 | "tags": {
265 | "references": [
266 | "local.resource_prefix",
267 | ],
268 | },
269 | "volume_id": {
270 | "references": [
271 | "aws_ebs_volume.web_host_storage",
272 | ],
273 | },
274 | },
275 | "count": {},
276 | "depends_on": [],
277 | "for_each": {},
278 | "mode": "managed",
279 | "module_address": "",
280 | "name": "example_snapshot",
281 | "provider_config_key": "aws",
282 | "provisioners": [],
283 | "type": "aws_ebs_snapshot",
284 | },
285 | "aws_ebs_volume.web_host_storage": {
286 | "address": "aws_ebs_volume.web_host_storage",
287 | "config": {
288 | "availability_zone": {
289 | "references": [
290 | "var.availability_zone",
291 | ],
292 | },
293 | "size": {
294 | "constant_value": 1,
295 | },
296 | "tags": {
297 | "references": [
298 | "local.resource_prefix",
299 | ],
300 | },
301 | },
302 | "count": {},
303 | "depends_on": [],
304 | "for_each": {},
305 | "mode": "managed",
306 | "module_address": "",
307 | "name": "web_host_storage",
308 | "provider_config_key": "aws",
309 | "provisioners": [],
310 | "type": "aws_ebs_volume",
311 | },
312 | "aws_ecr_repository.repository": {
313 | "address": "aws_ecr_repository.repository",
314 | "config": {
315 | "image_tag_mutability": {
316 | "constant_value": "MUTABLE",
317 | },
318 | "name": {
319 | "references": [
320 | "local.resource_prefix",
321 | ],
322 | },
323 | "tags": {
324 | "references": [
325 | "local.resource_prefix",
326 | ],
327 | },
328 | },
329 | "count": {},
330 | "depends_on": [],
331 | "for_each": {},
332 | "mode": "managed",
333 | "module_address": "",
334 | "name": "repository",
335 | "provider_config_key": "aws",
336 | "provisioners": [],
337 | "type": "aws_ecr_repository",
338 | },
339 | "aws_eks_cluster.eks_cluster": {
340 | "address": "aws_eks_cluster.eks_cluster",
341 | "config": {
342 | "name": {
343 | "references": [
344 | "local.eks_name",
345 | ],
346 | },
347 | "role_arn": {
348 | "references": [
349 | "aws_iam_role.iam_for_eks",
350 | ],
351 | },
352 | "vpc_config": [
353 | {
354 | "endpoint_private_access": {
355 | "constant_value": true,
356 | },
357 | "subnet_ids": {
358 | "references": [
359 | "aws_subnet.eks_subnet1",
360 | "aws_subnet.eks_subnet2",
361 | ],
362 | },
363 | },
364 | ],
365 | },
366 | "count": {},
367 | "depends_on": [
368 | "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSClusterPolicy",
369 | "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSServicePolicy",
370 | ],
371 | "for_each": {},
372 | "mode": "managed",
373 | "module_address": "",
374 | "name": "eks_cluster",
375 | "provider_config_key": "aws",
376 | "provisioners": [],
377 | "type": "aws_eks_cluster",
378 | },
379 | "aws_elasticsearch_domain.monitoring-framework": {
380 | "address": "aws_elasticsearch_domain.monitoring-framework",
381 | "config": {
382 | "cluster_config": [
383 | {
384 | "dedicated_master_count": {
385 | "constant_value": 1,
386 | },
387 | "dedicated_master_enabled": {
388 | "constant_value": false,
389 | },
390 | "dedicated_master_type": {
391 | "constant_value": "m4.large.elasticsearch",
392 | },
393 | "instance_count": {
394 | "constant_value": 1,
395 | },
396 | "instance_type": {
397 | "constant_value": "t2.small.elasticsearch",
398 | },
399 | },
400 | ],
401 | "domain_name": {
402 | "references": [
403 | "var.environment",
404 | ],
405 | },
406 | "ebs_options": [
407 | {
408 | "ebs_enabled": {
409 | "constant_value": true,
410 | },
411 | "volume_size": {
412 | "constant_value": 30,
413 | },
414 | },
415 | ],
416 | "elasticsearch_version": {
417 | "constant_value": "2.3",
418 | },
419 | },
420 | "count": {},
421 | "depends_on": [],
422 | "for_each": {},
423 | "mode": "managed",
424 | "module_address": "",
425 | "name": "monitoring-framework",
426 | "provider_config_key": "aws",
427 | "provisioners": [],
428 | "type": "aws_elasticsearch_domain",
429 | },
430 | "aws_elasticsearch_domain_policy.monitoring-framework-policy": {
431 | "address": "aws_elasticsearch_domain_policy.monitoring-framework-policy",
432 | "config": {
433 | "access_policies": {
434 | "references": [
435 | "data.aws_iam_policy_document.policy",
436 | ],
437 | },
438 | "domain_name": {
439 | "references": [
440 | "aws_elasticsearch_domain.monitoring-framework",
441 | ],
442 | },
443 | },
444 | "count": {},
445 | "depends_on": [],
446 | "for_each": {},
447 | "mode": "managed",
448 | "module_address": "",
449 | "name": "monitoring-framework-policy",
450 | "provider_config_key": "aws",
451 | "provisioners": [],
452 | "type": "aws_elasticsearch_domain_policy",
453 | },
454 | "aws_elb.weblb": {
455 | "address": "aws_elb.weblb",
456 | "config": {
457 | "connection_draining": {
458 | "constant_value": true,
459 | },
460 | "connection_draining_timeout": {
461 | "constant_value": 400,
462 | },
463 | "cross_zone_load_balancing": {
464 | "constant_value": true,
465 | },
466 | "health_check": [
467 | {
468 | "healthy_threshold": {
469 | "constant_value": 2,
470 | },
471 | "interval": {
472 | "constant_value": 30,
473 | },
474 | "target": {
475 | "constant_value": "HTTP:8000/",
476 | },
477 | "timeout": {
478 | "constant_value": 3,
479 | },
480 | "unhealthy_threshold": {
481 | "constant_value": 2,
482 | },
483 | },
484 | ],
485 | "idle_timeout": {
486 | "constant_value": 400,
487 | },
488 | "instances": {
489 | "references": [
490 | "aws_instance.web_host",
491 | ],
492 | },
493 | "listener": [
494 | {
495 | "instance_port": {
496 | "constant_value": 8000,
497 | },
498 | "instance_protocol": {
499 | "constant_value": "http",
500 | },
501 | "lb_port": {
502 | "constant_value": 80,
503 | },
504 | "lb_protocol": {
505 | "constant_value": "http",
506 | },
507 | },
508 | ],
509 | "name": {
510 | "constant_value": "weblb-terraform-elb",
511 | },
512 | "security_groups": {
513 | "references": [
514 | "aws_security_group.web-node",
515 | ],
516 | },
517 | "subnets": {
518 | "references": [
519 | "aws_subnet.web_subnet",
520 | ],
521 | },
522 | "tags": {
523 | "constant_value": {
524 | "Name": "foobar-terraform-elb",
525 | },
526 | },
527 | },
528 | "count": {},
529 | "depends_on": [],
530 | "for_each": {},
531 | "mode": "managed",
532 | "module_address": "",
533 | "name": "weblb",
534 | "provider_config_key": "aws",
535 | "provisioners": [],
536 | "type": "aws_elb",
537 | },
538 | "aws_flow_log.vpcflowlogs": {
539 | "address": "aws_flow_log.vpcflowlogs",
540 | "config": {
541 | "log_destination": {
542 | "references": [
543 | "aws_s3_bucket.flowbucket",
544 | ],
545 | },
546 | "log_destination_type": {
547 | "constant_value": "s3",
548 | },
549 | "tags": {
550 | "references": [
551 | "local.resource_prefix",
552 | "local.resource_prefix",
553 | ],
554 | },
555 | "traffic_type": {
556 | "constant_value": "ALL",
557 | },
558 | "vpc_id": {
559 | "references": [
560 | "aws_vpc.web_vpc",
561 | ],
562 | },
563 | },
564 | "count": {},
565 | "depends_on": [],
566 | "for_each": {},
567 | "mode": "managed",
568 | "module_address": "",
569 | "name": "vpcflowlogs",
570 | "provider_config_key": "aws",
571 | "provisioners": [],
572 | "type": "aws_flow_log",
573 | },
574 | "aws_iam_access_key.user": {
575 | "address": "aws_iam_access_key.user",
576 | "config": {
577 | "user": {
578 | "references": [
579 | "aws_iam_user.user",
580 | ],
581 | },
582 | },
583 | "count": {},
584 | "depends_on": [],
585 | "for_each": {},
586 | "mode": "managed",
587 | "module_address": "",
588 | "name": "user",
589 | "provider_config_key": "aws",
590 | "provisioners": [],
591 | "type": "aws_iam_access_key",
592 | },
593 | "aws_iam_instance_profile.ec2profile": {
594 | "address": "aws_iam_instance_profile.ec2profile",
595 | "config": {
596 | "name": {
597 | "references": [
598 | "local.resource_prefix",
599 | ],
600 | },
601 | "role": {
602 | "references": [
603 | "aws_iam_role.ec2role",
604 | ],
605 | },
606 | },
607 | "count": {},
608 | "depends_on": [],
609 | "for_each": {},
610 | "mode": "managed",
611 | "module_address": "",
612 | "name": "ec2profile",
613 | "provider_config_key": "aws",
614 | "provisioners": [],
615 | "type": "aws_iam_instance_profile",
616 | },
617 | "aws_iam_role.ec2role": {
618 | "address": "aws_iam_role.ec2role",
619 | "config": {
620 | "assume_role_policy": {
621 | "constant_value": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"ec2.amazonaws.com\"\n },\n \"Effect\": \"Allow\",\n \"Sid\": \"\"\n }\n ]\n}\n",
622 | },
623 | "name": {
624 | "references": [
625 | "local.resource_prefix",
626 | ],
627 | },
628 | "path": {
629 | "constant_value": "/",
630 | },
631 | "tags": {
632 | "references": [
633 | "local.resource_prefix",
634 | "local.resource_prefix",
635 | ],
636 | },
637 | },
638 | "count": {},
639 | "depends_on": [],
640 | "for_each": {},
641 | "mode": "managed",
642 | "module_address": "",
643 | "name": "ec2role",
644 | "provider_config_key": "aws",
645 | "provisioners": [],
646 | "type": "aws_iam_role",
647 | },
648 | "aws_iam_role.iam_for_eks": {
649 | "address": "aws_iam_role.iam_for_eks",
650 | "config": {
651 | "assume_role_policy": {
652 | "references": [
653 | "data.aws_iam_policy_document.iam_policy_eks",
654 | ],
655 | },
656 | "name": {
657 | "references": [
658 | "local.resource_prefix",
659 | ],
660 | },
661 | },
662 | "count": {},
663 | "depends_on": [],
664 | "for_each": {},
665 | "mode": "managed",
666 | "module_address": "",
667 | "name": "iam_for_eks",
668 | "provider_config_key": "aws",
669 | "provisioners": [],
670 | "type": "aws_iam_role",
671 | },
672 | "aws_iam_role.iam_for_lambda": {
673 | "address": "aws_iam_role.iam_for_lambda",
674 | "config": {
675 | "assume_role_policy": {
676 | "constant_value": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"lambda.amazonaws.com\"\n },\n \"Effect\": \"Allow\",\n \"Sid\": \"\"\n }\n ]\n}\n",
677 | },
678 | "name": {
679 | "references": [
680 | "local.resource_prefix",
681 | ],
682 | },
683 | },
684 | "count": {},
685 | "depends_on": [],
686 | "for_each": {},
687 | "mode": "managed",
688 | "module_address": "",
689 | "name": "iam_for_lambda",
690 | "provider_config_key": "aws",
691 | "provisioners": [],
692 | "type": "aws_iam_role",
693 | },
694 | "aws_iam_role_policy.ec2policy": {
695 | "address": "aws_iam_role_policy.ec2policy",
696 | "config": {
697 | "name": {
698 | "references": [
699 | "local.resource_prefix",
700 | ],
701 | },
702 | "policy": {
703 | "constant_value": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"s3:*\",\n \"ec2:*\",\n \"rds:*\"\n ],\n \"Effect\": \"Allow\",\n \"Resource\": \"*\"\n }\n ]\n}\n",
704 | },
705 | "role": {
706 | "references": [
707 | "aws_iam_role.ec2role",
708 | ],
709 | },
710 | },
711 | "count": {},
712 | "depends_on": [],
713 | "for_each": {},
714 | "mode": "managed",
715 | "module_address": "",
716 | "name": "ec2policy",
717 | "provider_config_key": "aws",
718 | "provisioners": [],
719 | "type": "aws_iam_role_policy",
720 | },
721 | "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSClusterPolicy": {
722 | "address": "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSClusterPolicy",
723 | "config": {
724 | "policy_arn": {
725 | "constant_value": "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
726 | },
727 | "role": {
728 | "references": [
729 | "aws_iam_role.iam_for_eks",
730 | ],
731 | },
732 | },
733 | "count": {},
734 | "depends_on": [],
735 | "for_each": {},
736 | "mode": "managed",
737 | "module_address": "",
738 | "name": "policy_attachment-AmazonEKSClusterPolicy",
739 | "provider_config_key": "aws",
740 | "provisioners": [],
741 | "type": "aws_iam_role_policy_attachment",
742 | },
743 | "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSServicePolicy": {
744 | "address": "aws_iam_role_policy_attachment.policy_attachment-AmazonEKSServicePolicy",
745 | "config": {
746 | "policy_arn": {
747 | "constant_value": "arn:aws:iam::aws:policy/AmazonEKSServicePolicy",
748 | },
749 | "role": {
750 | "references": [
751 | "aws_iam_role.iam_for_eks",
752 | ],
753 | },
754 | },
755 | "count": {},
756 | "depends_on": [],
757 | "for_each": {},
758 | "mode": "managed",
759 | "module_address": "",
760 | "name": "policy_attachment-AmazonEKSServicePolicy",
761 | "provider_config_key": "aws",
762 | "provisioners": [],
763 | "type": "aws_iam_role_policy_attachment",
764 | },
765 | "aws_iam_user.user": {
766 | "address": "aws_iam_user.user",
767 | "config": {
768 | "force_destroy": {
769 | "constant_value": true,
770 | },
771 | "name": {
772 | "references": [
773 | "local.resource_prefix",
774 | ],
775 | },
776 | "tags": {
777 | "references": [
778 | "local.resource_prefix",
779 | "local.resource_prefix",
780 | ],
781 | },
782 | },
783 | "count": {},
784 | "depends_on": [],
785 | "for_each": {},
786 | "mode": "managed",
787 | "module_address": "",
788 | "name": "user",
789 | "provider_config_key": "aws",
790 | "provisioners": [],
791 | "type": "aws_iam_user",
792 | },
793 | "aws_iam_user_policy.userpolicy": {
794 | "address": "aws_iam_user_policy.userpolicy",
795 | "config": {
796 | "name": {
797 | "constant_value": "excess_policy",
798 | },
799 | "policy": {
800 | "constant_value": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"ec2:*\",\n \"s3:*\",\n \"lambda:*\",\n \"cloudwatch:*\"\n ],\n \"Effect\": \"Allow\",\n \"Resource\": \"*\"\n }\n ]\n}\n",
801 | },
802 | "user": {
803 | "references": [
804 | "aws_iam_user.user",
805 | ],
806 | },
807 | },
808 | "count": {},
809 | "depends_on": [],
810 | "for_each": {},
811 | "mode": "managed",
812 | "module_address": "",
813 | "name": "userpolicy",
814 | "provider_config_key": "aws",
815 | "provisioners": [],
816 | "type": "aws_iam_user_policy",
817 | },
818 | "aws_instance.db_app": {
819 | "address": "aws_instance.db_app",
820 | "config": {
821 | "ami": {
822 | "references": [
823 | "data.aws_ami.amazon-linux-2",
824 | ],
825 | },
826 | "iam_instance_profile": {
827 | "references": [
828 | "aws_iam_instance_profile.ec2profile",
829 | ],
830 | },
831 | "instance_type": {
832 | "constant_value": "t2.nano",
833 | },
834 | "subnet_id": {
835 | "references": [
836 | "aws_subnet.web_subnet",
837 | ],
838 | },
839 | "tags": {
840 | "references": [
841 | "local.resource_prefix",
842 | ],
843 | },
844 | "user_data": {
845 | "references": [
846 | "aws_db_instance.default",
847 | "aws_db_instance.default",
848 | "var.password",
849 | "aws_db_instance.default",
850 | ],
851 | },
852 | "vpc_security_group_ids": {
853 | "references": [
854 | "aws_security_group.web-node",
855 | ],
856 | },
857 | },
858 | "count": {},
859 | "depends_on": [],
860 | "for_each": {},
861 | "mode": "managed",
862 | "module_address": "",
863 | "name": "db_app",
864 | "provider_config_key": "aws",
865 | "provisioners": [],
866 | "type": "aws_instance",
867 | },
868 | "aws_instance.web_host": {
869 | "address": "aws_instance.web_host",
870 | "config": {
871 | "ami": {
872 | "references": [
873 | "var.ami",
874 | ],
875 | },
876 | "instance_type": {
877 | "constant_value": "t2.nano",
878 | },
879 | "subnet_id": {
880 | "references": [
881 | "aws_subnet.web_subnet",
882 | ],
883 | },
884 | "tags": {
885 | "references": [
886 | "local.resource_prefix",
887 | ],
888 | },
889 | "user_data": {
890 | "constant_value": "#! /bin/bash\nsudo apt-get update\nsudo apt-get install -y apache2\nsudo systemctl start apache2\nsudo systemctl enable apache2\nexport AWS_ACCESS_KEY_ID={{REDACTED}}\nexport AWS_SECRET_ACCESS_KEY={{REDACTED}}\nexport AWS_DEFAULT_REGION=us-west-2\necho \"Deployed via Terraform
\" | sudo tee /var/www/html/index.html\n",
891 | },
892 | "vpc_security_group_ids": {
893 | "references": [
894 | "aws_security_group.web-node",
895 | ],
896 | },
897 | },
898 | "count": {},
899 | "depends_on": [],
900 | "for_each": {},
901 | "mode": "managed",
902 | "module_address": "",
903 | "name": "web_host",
904 | "provider_config_key": "aws",
905 | "provisioners": [],
906 | "type": "aws_instance",
907 | },
908 | "aws_internet_gateway.web_igw": {
909 | "address": "aws_internet_gateway.web_igw",
910 | "config": {
911 | "tags": {
912 | "references": [
913 | "local.resource_prefix",
914 | ],
915 | },
916 | "vpc_id": {
917 | "references": [
918 | "aws_vpc.web_vpc",
919 | ],
920 | },
921 | },
922 | "count": {},
923 | "depends_on": [],
924 | "for_each": {},
925 | "mode": "managed",
926 | "module_address": "",
927 | "name": "web_igw",
928 | "provider_config_key": "aws",
929 | "provisioners": [],
930 | "type": "aws_internet_gateway",
931 | },
932 | "aws_kms_alias.logs_key_alias": {
933 | "address": "aws_kms_alias.logs_key_alias",
934 | "config": {
935 | "name": {
936 | "references": [
937 | "local.resource_prefix",
938 | ],
939 | },
940 | "target_key_id": {
941 | "references": [
942 | "aws_kms_key.logs_key",
943 | ],
944 | },
945 | },
946 | "count": {},
947 | "depends_on": [],
948 | "for_each": {},
949 | "mode": "managed",
950 | "module_address": "",
951 | "name": "logs_key_alias",
952 | "provider_config_key": "aws",
953 | "provisioners": [],
954 | "type": "aws_kms_alias",
955 | },
956 | "aws_kms_key.logs_key": {
957 | "address": "aws_kms_key.logs_key",
958 | "config": {
959 | "deletion_window_in_days": {
960 | "constant_value": 7,
961 | },
962 | "description": {
963 | "references": [
964 | "local.resource_prefix",
965 | ],
966 | },
967 | },
968 | "count": {},
969 | "depends_on": [],
970 | "for_each": {},
971 | "mode": "managed",
972 | "module_address": "",
973 | "name": "logs_key",
974 | "provider_config_key": "aws",
975 | "provisioners": [],
976 | "type": "aws_kms_key",
977 | },
978 | "aws_lambda_function.analysis_lambda": {
979 | "address": "aws_lambda_function.analysis_lambda",
980 | "config": {
981 | "environment": [
982 | {
983 | "variables": {
984 | "constant_value": {
985 | "access_key": "{{REDACTED}}",
986 | "secret_key": "{{REDACTED}}",
987 | },
988 | },
989 | },
990 | ],
991 | "filename": {
992 | "constant_value": "resources/lambda_function_payload.zip",
993 | },
994 | "function_name": {
995 | "references": [
996 | "local.resource_prefix",
997 | ],
998 | },
999 | "handler": {
1000 | "constant_value": "exports.test",
1001 | },
1002 | "role": {
1003 | "references": [
1004 | "aws_iam_role.iam_for_lambda",
1005 | ],
1006 | },
1007 | "runtime": {
1008 | "constant_value": "nodejs12.x",
1009 | },
1010 | "source_code_hash": {
1011 | "constant_value": null,
1012 | },
1013 | },
1014 | "count": {},
1015 | "depends_on": [],
1016 | "for_each": {},
1017 | "mode": "managed",
1018 | "module_address": "",
1019 | "name": "analysis_lambda",
1020 | "provider_config_key": "aws",
1021 | "provisioners": [],
1022 | "type": "aws_lambda_function",
1023 | },
1024 | "aws_neptune_cluster.default": {
1025 | "address": "aws_neptune_cluster.default",
1026 | "config": {
1027 | "apply_immediately": {
1028 | "constant_value": true,
1029 | },
1030 | "backup_retention_period": {
1031 | "constant_value": 5,
1032 | },
1033 | "cluster_identifier": {
1034 | "references": [
1035 | "var.neptune-dbname",
1036 | ],
1037 | },
1038 | "engine": {
1039 | "constant_value": "neptune",
1040 | },
1041 | "iam_database_authentication_enabled": {
1042 | "constant_value": false,
1043 | },
1044 | "preferred_backup_window": {
1045 | "constant_value": "07:00-09:00",
1046 | },
1047 | "skip_final_snapshot": {
1048 | "constant_value": true,
1049 | },
1050 | "storage_encrypted": {
1051 | "constant_value": false,
1052 | },
1053 | },
1054 | "count": {},
1055 | "depends_on": [],
1056 | "for_each": {},
1057 | "mode": "managed",
1058 | "module_address": "",
1059 | "name": "default",
1060 | "provider_config_key": "aws",
1061 | "provisioners": [],
1062 | "type": "aws_neptune_cluster",
1063 | },
1064 | "aws_neptune_cluster_instance.default": {
1065 | "address": "aws_neptune_cluster_instance.default",
1066 | "config": {
1067 | "apply_immediately": {
1068 | "constant_value": true,
1069 | },
1070 | "cluster_identifier": {
1071 | "references": [
1072 | "aws_neptune_cluster.default",
1073 | ],
1074 | },
1075 | "engine": {
1076 | "constant_value": "neptune",
1077 | },
1078 | "instance_class": {
1079 | "constant_value": "db.t3.medium",
1080 | },
1081 | },
1082 | "count": {
1083 | "constant_value": 1,
1084 | },
1085 | "depends_on": [],
1086 | "for_each": {},
1087 | "mode": "managed",
1088 | "module_address": "",
1089 | "name": "default",
1090 | "provider_config_key": "aws",
1091 | "provisioners": [],
1092 | "type": "aws_neptune_cluster_instance",
1093 | },
1094 | "aws_neptune_cluster_snapshot.default": {
1095 | "address": "aws_neptune_cluster_snapshot.default",
1096 | "config": {
1097 | "db_cluster_identifier": {
1098 | "references": [
1099 | "aws_neptune_cluster.default",
1100 | ],
1101 | },
1102 | "db_cluster_snapshot_identifier": {
1103 | "constant_value": "resourcetestsnapshot1",
1104 | },
1105 | },
1106 | "count": {},
1107 | "depends_on": [],
1108 | "for_each": {},
1109 | "mode": "managed",
1110 | "module_address": "",
1111 | "name": "default",
1112 | "provider_config_key": "aws",
1113 | "provisioners": [],
1114 | "type": "aws_neptune_cluster_snapshot",
1115 | },
1116 | "aws_network_interface.web-eni": {
1117 | "address": "aws_network_interface.web-eni",
1118 | "config": {
1119 | "private_ips": {
1120 | "constant_value": [
1121 | "172.16.10.100",
1122 | ],
1123 | },
1124 | "subnet_id": {
1125 | "references": [
1126 | "aws_subnet.web_subnet",
1127 | ],
1128 | },
1129 | "tags": {
1130 | "references": [
1131 | "local.resource_prefix",
1132 | ],
1133 | },
1134 | },
1135 | "count": {},
1136 | "depends_on": [],
1137 | "for_each": {},
1138 | "mode": "managed",
1139 | "module_address": "",
1140 | "name": "web-eni",
1141 | "provider_config_key": "aws",
1142 | "provisioners": [],
1143 | "type": "aws_network_interface",
1144 | },
1145 | "aws_route.public_internet_gateway": {
1146 | "address": "aws_route.public_internet_gateway",
1147 | "config": {
1148 | "destination_cidr_block": {
1149 | "constant_value": "0.0.0.0/0",
1150 | },
1151 | "gateway_id": {
1152 | "references": [
1153 | "aws_internet_gateway.web_igw",
1154 | ],
1155 | },
1156 | "route_table_id": {
1157 | "references": [
1158 | "aws_route_table.web_rtb",
1159 | ],
1160 | },
1161 | "timeouts": {
1162 | "constant_value": null,
1163 | },
1164 | },
1165 | "count": {},
1166 | "depends_on": [],
1167 | "for_each": {},
1168 | "mode": "managed",
1169 | "module_address": "",
1170 | "name": "public_internet_gateway",
1171 | "provider_config_key": "aws",
1172 | "provisioners": [],
1173 | "type": "aws_route",
1174 | },
1175 | "aws_route_table.web_rtb": {
1176 | "address": "aws_route_table.web_rtb",
1177 | "config": {
1178 | "tags": {
1179 | "references": [
1180 | "local.resource_prefix",
1181 | ],
1182 | },
1183 | "vpc_id": {
1184 | "references": [
1185 | "aws_vpc.web_vpc",
1186 | ],
1187 | },
1188 | },
1189 | "count": {},
1190 | "depends_on": [],
1191 | "for_each": {},
1192 | "mode": "managed",
1193 | "module_address": "",
1194 | "name": "web_rtb",
1195 | "provider_config_key": "aws",
1196 | "provisioners": [],
1197 | "type": "aws_route_table",
1198 | },
1199 | "aws_route_table_association.rtbassoc": {
1200 | "address": "aws_route_table_association.rtbassoc",
1201 | "config": {
1202 | "route_table_id": {
1203 | "references": [
1204 | "aws_route_table.web_rtb",
1205 | ],
1206 | },
1207 | "subnet_id": {
1208 | "references": [
1209 | "aws_subnet.web_subnet",
1210 | ],
1211 | },
1212 | },
1213 | "count": {},
1214 | "depends_on": [],
1215 | "for_each": {},
1216 | "mode": "managed",
1217 | "module_address": "",
1218 | "name": "rtbassoc",
1219 | "provider_config_key": "aws",
1220 | "provisioners": [],
1221 | "type": "aws_route_table_association",
1222 | },
1223 | "aws_route_table_association.rtbassoc2": {
1224 | "address": "aws_route_table_association.rtbassoc2",
1225 | "config": {
1226 | "route_table_id": {
1227 | "references": [
1228 | "aws_route_table.web_rtb",
1229 | ],
1230 | },
1231 | "subnet_id": {
1232 | "references": [
1233 | "aws_subnet.web_subnet2",
1234 | ],
1235 | },
1236 | },
1237 | "count": {},
1238 | "depends_on": [],
1239 | "for_each": {},
1240 | "mode": "managed",
1241 | "module_address": "",
1242 | "name": "rtbassoc2",
1243 | "provider_config_key": "aws",
1244 | "provisioners": [],
1245 | "type": "aws_route_table_association",
1246 | },
1247 | "aws_s3_bucket.data": {
1248 | "address": "aws_s3_bucket.data",
1249 | "config": {
1250 | "acl": {
1251 | "constant_value": "public-read",
1252 | },
1253 | "bucket": {
1254 | "references": [
1255 | "local.resource_prefix",
1256 | ],
1257 | },
1258 | "force_destroy": {
1259 | "constant_value": true,
1260 | },
1261 | "tags": {
1262 | "references": [
1263 | "local.resource_prefix",
1264 | "local.resource_prefix",
1265 | ],
1266 | },
1267 | },
1268 | "count": {},
1269 | "depends_on": [],
1270 | "for_each": {},
1271 | "mode": "managed",
1272 | "module_address": "",
1273 | "name": "data",
1274 | "provider_config_key": "aws",
1275 | "provisioners": [],
1276 | "type": "aws_s3_bucket",
1277 | },
1278 | "aws_s3_bucket.data_science": {
1279 | "address": "aws_s3_bucket.data_science",
1280 | "config": {
1281 | "acl": {
1282 | "constant_value": "private",
1283 | },
1284 | "bucket": {
1285 | "references": [
1286 | "local.resource_prefix",
1287 | ],
1288 | },
1289 | "force_destroy": {
1290 | "constant_value": true,
1291 | },
1292 | "logging": [
1293 | {
1294 | "target_bucket": {
1295 | "references": [
1296 | "aws_s3_bucket.logs",
1297 | ],
1298 | },
1299 | "target_prefix": {
1300 | "constant_value": "log/",
1301 | },
1302 | },
1303 | ],
1304 | "versioning": [
1305 | {
1306 | "enabled": {
1307 | "constant_value": true,
1308 | },
1309 | },
1310 | ],
1311 | },
1312 | "count": {},
1313 | "depends_on": [],
1314 | "for_each": {},
1315 | "mode": "managed",
1316 | "module_address": "",
1317 | "name": "data_science",
1318 | "provider_config_key": "aws",
1319 | "provisioners": [],
1320 | "type": "aws_s3_bucket",
1321 | },
1322 | "aws_s3_bucket.financials": {
1323 | "address": "aws_s3_bucket.financials",
1324 | "config": {
1325 | "acl": {
1326 | "constant_value": "private",
1327 | },
1328 | "bucket": {
1329 | "references": [
1330 | "local.resource_prefix",
1331 | ],
1332 | },
1333 | "force_destroy": {
1334 | "constant_value": true,
1335 | },
1336 | "tags": {
1337 | "references": [
1338 | "local.resource_prefix",
1339 | "local.resource_prefix",
1340 | ],
1341 | },
1342 | },
1343 | "count": {},
1344 | "depends_on": [],
1345 | "for_each": {},
1346 | "mode": "managed",
1347 | "module_address": "",
1348 | "name": "financials",
1349 | "provider_config_key": "aws",
1350 | "provisioners": [],
1351 | "type": "aws_s3_bucket",
1352 | },
1353 | "aws_s3_bucket.flowbucket": {
1354 | "address": "aws_s3_bucket.flowbucket",
1355 | "config": {
1356 | "bucket": {
1357 | "references": [
1358 | "local.resource_prefix",
1359 | ],
1360 | },
1361 | "force_destroy": {
1362 | "constant_value": true,
1363 | },
1364 | "tags": {
1365 | "references": [
1366 | "local.resource_prefix",
1367 | "local.resource_prefix",
1368 | ],
1369 | },
1370 | },
1371 | "count": {},
1372 | "depends_on": [],
1373 | "for_each": {},
1374 | "mode": "managed",
1375 | "module_address": "",
1376 | "name": "flowbucket",
1377 | "provider_config_key": "aws",
1378 | "provisioners": [],
1379 | "type": "aws_s3_bucket",
1380 | },
1381 | "aws_s3_bucket.logs": {
1382 | "address": "aws_s3_bucket.logs",
1383 | "config": {
1384 | "acl": {
1385 | "constant_value": "log-delivery-write",
1386 | },
1387 | "bucket": {
1388 | "references": [
1389 | "local.resource_prefix",
1390 | ],
1391 | },
1392 | "force_destroy": {
1393 | "constant_value": true,
1394 | },
1395 | "server_side_encryption_configuration": [
1396 | {
1397 | "rule": [
1398 | {
1399 | "apply_server_side_encryption_by_default": [
1400 | {
1401 | "kms_master_key_id": {
1402 | "references": [
1403 | "aws_kms_key.logs_key",
1404 | ],
1405 | },
1406 | "sse_algorithm": {
1407 | "constant_value": "aws:kms",
1408 | },
1409 | },
1410 | ],
1411 | },
1412 | ],
1413 | },
1414 | ],
1415 | "tags": {
1416 | "references": [
1417 | "local.resource_prefix",
1418 | "local.resource_prefix",
1419 | ],
1420 | },
1421 | "versioning": [
1422 | {
1423 | "enabled": {
1424 | "constant_value": true,
1425 | },
1426 | },
1427 | ],
1428 | },
1429 | "count": {},
1430 | "depends_on": [],
1431 | "for_each": {},
1432 | "mode": "managed",
1433 | "module_address": "",
1434 | "name": "logs",
1435 | "provider_config_key": "aws",
1436 | "provisioners": [],
1437 | "type": "aws_s3_bucket",
1438 | },
1439 | "aws_s3_bucket.operations": {
1440 | "address": "aws_s3_bucket.operations",
1441 | "config": {
1442 | "acl": {
1443 | "constant_value": "private",
1444 | },
1445 | "bucket": {
1446 | "references": [
1447 | "local.resource_prefix",
1448 | ],
1449 | },
1450 | "force_destroy": {
1451 | "constant_value": true,
1452 | },
1453 | "tags": {
1454 | "references": [
1455 | "local.resource_prefix",
1456 | "local.resource_prefix",
1457 | ],
1458 | },
1459 | "versioning": [
1460 | {
1461 | "enabled": {
1462 | "constant_value": true,
1463 | },
1464 | },
1465 | ],
1466 | },
1467 | "count": {},
1468 | "depends_on": [],
1469 | "for_each": {},
1470 | "mode": "managed",
1471 | "module_address": "",
1472 | "name": "operations",
1473 | "provider_config_key": "aws",
1474 | "provisioners": [],
1475 | "type": "aws_s3_bucket",
1476 | },
1477 | "aws_s3_bucket_object.data_object": {
1478 | "address": "aws_s3_bucket_object.data_object",
1479 | "config": {
1480 | "bucket": {
1481 | "references": [
1482 | "aws_s3_bucket.data",
1483 | ],
1484 | },
1485 | "key": {
1486 | "constant_value": "customer-master.xlsx",
1487 | },
1488 | "source": {
1489 | "constant_value": "resources/customer-master.xlsx",
1490 | },
1491 | "tags": {
1492 | "references": [
1493 | "local.resource_prefix",
1494 | "local.resource_prefix",
1495 | ],
1496 | },
1497 | },
1498 | "count": {},
1499 | "depends_on": [],
1500 | "for_each": {},
1501 | "mode": "managed",
1502 | "module_address": "",
1503 | "name": "data_object",
1504 | "provider_config_key": "aws",
1505 | "provisioners": [],
1506 | "type": "aws_s3_bucket_object",
1507 | },
1508 | "aws_security_group.default": {
1509 | "address": "aws_security_group.default",
1510 | "config": {
1511 | "name": {
1512 | "references": [
1513 | "local.resource_prefix",
1514 | ],
1515 | },
1516 | "tags": {
1517 | "references": [
1518 | "local.resource_prefix",
1519 | "local.resource_prefix",
1520 | ],
1521 | },
1522 | "vpc_id": {
1523 | "references": [
1524 | "aws_vpc.web_vpc",
1525 | ],
1526 | },
1527 | },
1528 | "count": {},
1529 | "depends_on": [],
1530 | "for_each": {},
1531 | "mode": "managed",
1532 | "module_address": "",
1533 | "name": "default",
1534 | "provider_config_key": "aws",
1535 | "provisioners": [],
1536 | "type": "aws_security_group",
1537 | },
1538 | "aws_security_group.web-node": {
1539 | "address": "aws_security_group.web-node",
1540 | "config": {
1541 | "description": {
1542 | "references": [
1543 | "local.resource_prefix",
1544 | ],
1545 | },
1546 | "name": {
1547 | "references": [
1548 | "local.resource_prefix",
1549 | ],
1550 | },
1551 | "vpc_id": {
1552 | "references": [
1553 | "aws_vpc.web_vpc",
1554 | ],
1555 | },
1556 | },
1557 | "count": {},
1558 | "depends_on": [
1559 | "aws_vpc.web_vpc",
1560 | ],
1561 | "for_each": {},
1562 | "mode": "managed",
1563 | "module_address": "",
1564 | "name": "web-node",
1565 | "provider_config_key": "aws",
1566 | "provisioners": [],
1567 | "type": "aws_security_group",
1568 | },
1569 | "aws_security_group_rule.egress": {
1570 | "address": "aws_security_group_rule.egress",
1571 | "config": {
1572 | "cidr_blocks": {
1573 | "constant_value": [
1574 | "0.0.0.0/0",
1575 | ],
1576 | },
1577 | "from_port": {
1578 | "constant_value": 0,
1579 | },
1580 | "protocol": {
1581 | "constant_value": "-1",
1582 | },
1583 | "security_group_id": {
1584 | "references": [
1585 | "aws_security_group.default",
1586 | ],
1587 | },
1588 | "to_port": {
1589 | "constant_value": 0,
1590 | },
1591 | "type": {
1592 | "constant_value": "egress",
1593 | },
1594 | },
1595 | "count": {},
1596 | "depends_on": [],
1597 | "for_each": {},
1598 | "mode": "managed",
1599 | "module_address": "",
1600 | "name": "egress",
1601 | "provider_config_key": "aws",
1602 | "provisioners": [],
1603 | "type": "aws_security_group_rule",
1604 | },
1605 | "aws_security_group_rule.ingress": {
1606 | "address": "aws_security_group_rule.ingress",
1607 | "config": {
1608 | "cidr_blocks": {
1609 | "references": [
1610 | "aws_vpc.web_vpc",
1611 | ],
1612 | },
1613 | "from_port": {
1614 | "constant_value": "3306",
1615 | },
1616 | "protocol": {
1617 | "constant_value": "tcp",
1618 | },
1619 | "security_group_id": {
1620 | "references": [
1621 | "aws_security_group.default",
1622 | ],
1623 | },
1624 | "to_port": {
1625 | "constant_value": "3306",
1626 | },
1627 | "type": {
1628 | "constant_value": "ingress",
1629 | },
1630 | },
1631 | "count": {},
1632 | "depends_on": [],
1633 | "for_each": {},
1634 | "mode": "managed",
1635 | "module_address": "",
1636 | "name": "ingress",
1637 | "provider_config_key": "aws",
1638 | "provisioners": [],
1639 | "type": "aws_security_group_rule",
1640 | },
1641 | "aws_subnet.eks_subnet1": {
1642 | "address": "aws_subnet.eks_subnet1",
1643 | "config": {
1644 | "availability_zone": {
1645 | "references": [
1646 | "var.availability_zone",
1647 | ],
1648 | },
1649 | "cidr_block": {
1650 | "constant_value": "10.10.10.0/24",
1651 | },
1652 | "map_public_ip_on_launch": {
1653 | "constant_value": true,
1654 | },
1655 | "tags": {
1656 | "references": [
1657 | "local.resource_prefix",
1658 | "local.eks_name",
1659 | ],
1660 | },
1661 | "vpc_id": {
1662 | "references": [
1663 | "aws_vpc.eks_vpc",
1664 | ],
1665 | },
1666 | },
1667 | "count": {},
1668 | "depends_on": [],
1669 | "for_each": {},
1670 | "mode": "managed",
1671 | "module_address": "",
1672 | "name": "eks_subnet1",
1673 | "provider_config_key": "aws",
1674 | "provisioners": [],
1675 | "type": "aws_subnet",
1676 | },
1677 | "aws_subnet.eks_subnet2": {
1678 | "address": "aws_subnet.eks_subnet2",
1679 | "config": {
1680 | "availability_zone": {
1681 | "references": [
1682 | "var.availability_zone2",
1683 | ],
1684 | },
1685 | "cidr_block": {
1686 | "constant_value": "10.10.11.0/24",
1687 | },
1688 | "map_public_ip_on_launch": {
1689 | "constant_value": true,
1690 | },
1691 | "tags": {
1692 | "references": [
1693 | "local.resource_prefix",
1694 | "local.eks_name",
1695 | ],
1696 | },
1697 | "vpc_id": {
1698 | "references": [
1699 | "aws_vpc.eks_vpc",
1700 | ],
1701 | },
1702 | },
1703 | "count": {},
1704 | "depends_on": [],
1705 | "for_each": {},
1706 | "mode": "managed",
1707 | "module_address": "",
1708 | "name": "eks_subnet2",
1709 | "provider_config_key": "aws",
1710 | "provisioners": [],
1711 | "type": "aws_subnet",
1712 | },
1713 | "aws_subnet.web_subnet": {
1714 | "address": "aws_subnet.web_subnet",
1715 | "config": {
1716 | "availability_zone": {
1717 | "references": [
1718 | "var.availability_zone",
1719 | ],
1720 | },
1721 | "cidr_block": {
1722 | "constant_value": "172.16.10.0/24",
1723 | },
1724 | "map_public_ip_on_launch": {
1725 | "constant_value": true,
1726 | },
1727 | "tags": {
1728 | "references": [
1729 | "local.resource_prefix",
1730 | ],
1731 | },
1732 | "vpc_id": {
1733 | "references": [
1734 | "aws_vpc.web_vpc",
1735 | ],
1736 | },
1737 | },
1738 | "count": {},
1739 | "depends_on": [],
1740 | "for_each": {},
1741 | "mode": "managed",
1742 | "module_address": "",
1743 | "name": "web_subnet",
1744 | "provider_config_key": "aws",
1745 | "provisioners": [],
1746 | "type": "aws_subnet",
1747 | },
1748 | "aws_subnet.web_subnet2": {
1749 | "address": "aws_subnet.web_subnet2",
1750 | "config": {
1751 | "availability_zone": {
1752 | "references": [
1753 | "var.availability_zone2",
1754 | ],
1755 | },
1756 | "cidr_block": {
1757 | "constant_value": "172.16.11.0/24",
1758 | },
1759 | "map_public_ip_on_launch": {
1760 | "constant_value": true,
1761 | },
1762 | "tags": {
1763 | "references": [
1764 | "local.resource_prefix",
1765 | ],
1766 | },
1767 | "vpc_id": {
1768 | "references": [
1769 | "aws_vpc.web_vpc",
1770 | ],
1771 | },
1772 | },
1773 | "count": {},
1774 | "depends_on": [],
1775 | "for_each": {},
1776 | "mode": "managed",
1777 | "module_address": "",
1778 | "name": "web_subnet2",
1779 | "provider_config_key": "aws",
1780 | "provisioners": [],
1781 | "type": "aws_subnet",
1782 | },
1783 | "aws_volume_attachment.ebs_att": {
1784 | "address": "aws_volume_attachment.ebs_att",
1785 | "config": {
1786 | "device_name": {
1787 | "constant_value": "/dev/sdh",
1788 | },
1789 | "instance_id": {
1790 | "references": [
1791 | "aws_instance.web_host",
1792 | ],
1793 | },
1794 | "volume_id": {
1795 | "references": [
1796 | "aws_ebs_volume.web_host_storage",
1797 | ],
1798 | },
1799 | },
1800 | "count": {},
1801 | "depends_on": [],
1802 | "for_each": {},
1803 | "mode": "managed",
1804 | "module_address": "",
1805 | "name": "ebs_att",
1806 | "provider_config_key": "aws",
1807 | "provisioners": [],
1808 | "type": "aws_volume_attachment",
1809 | },
1810 | "aws_vpc.eks_vpc": {
1811 | "address": "aws_vpc.eks_vpc",
1812 | "config": {
1813 | "cidr_block": {
1814 | "constant_value": "10.10.0.0/16",
1815 | },
1816 | "enable_dns_hostnames": {
1817 | "constant_value": true,
1818 | },
1819 | "enable_dns_support": {
1820 | "constant_value": true,
1821 | },
1822 | "tags": {
1823 | "references": [
1824 | "local.resource_prefix",
1825 | ],
1826 | },
1827 | },
1828 | "count": {},
1829 | "depends_on": [],
1830 | "for_each": {},
1831 | "mode": "managed",
1832 | "module_address": "",
1833 | "name": "eks_vpc",
1834 | "provider_config_key": "aws",
1835 | "provisioners": [],
1836 | "type": "aws_vpc",
1837 | },
1838 | "aws_vpc.web_vpc": {
1839 | "address": "aws_vpc.web_vpc",
1840 | "config": {
1841 | "cidr_block": {
1842 | "constant_value": "172.16.0.0/16",
1843 | },
1844 | "enable_dns_hostnames": {
1845 | "constant_value": true,
1846 | },
1847 | "enable_dns_support": {
1848 | "constant_value": true,
1849 | },
1850 | "tags": {
1851 | "references": [
1852 | "local.resource_prefix",
1853 | ],
1854 | },
1855 | },
1856 | "count": {},
1857 | "depends_on": [],
1858 | "for_each": {},
1859 | "mode": "managed",
1860 | "module_address": "",
1861 | "name": "web_vpc",
1862 | "provider_config_key": "aws",
1863 | "provisioners": [],
1864 | "type": "aws_vpc",
1865 | },
1866 | "data.aws_ami.amazon-linux-2": {
1867 | "address": "data.aws_ami.amazon-linux-2",
1868 | "config": {
1869 | "filter": [
1870 | {
1871 | "name": {
1872 | "constant_value": "owner-alias",
1873 | },
1874 | "values": {
1875 | "constant_value": [
1876 | "amazon",
1877 | ],
1878 | },
1879 | },
1880 | {
1881 | "name": {
1882 | "constant_value": "name",
1883 | },
1884 | "values": {
1885 | "constant_value": [
1886 | "amzn2-ami-hvm-*-x86_64-ebs",
1887 | ],
1888 | },
1889 | },
1890 | ],
1891 | "most_recent": {
1892 | "constant_value": true,
1893 | },
1894 | "owners": {
1895 | "constant_value": [
1896 | "amazon",
1897 | ],
1898 | },
1899 | },
1900 | "count": {},
1901 | "depends_on": [],
1902 | "for_each": {},
1903 | "mode": "data",
1904 | "module_address": "",
1905 | "name": "amazon-linux-2",
1906 | "provider_config_key": "aws",
1907 | "provisioners": [],
1908 | "type": "aws_ami",
1909 | },
1910 | "data.aws_caller_identity.current": {
1911 | "address": "data.aws_caller_identity.current",
1912 | "config": {},
1913 | "count": {},
1914 | "depends_on": [],
1915 | "for_each": {},
1916 | "mode": "data",
1917 | "module_address": "",
1918 | "name": "current",
1919 | "provider_config_key": "aws",
1920 | "provisioners": [],
1921 | "type": "aws_caller_identity",
1922 | },
1923 | "data.aws_iam_policy_document.iam_policy_eks": {
1924 | "address": "data.aws_iam_policy_document.iam_policy_eks",
1925 | "config": {
1926 | "statement": [
1927 | {
1928 | "actions": {
1929 | "constant_value": [
1930 | "sts:AssumeRole",
1931 | ],
1932 | },
1933 | "effect": {
1934 | "constant_value": "Allow",
1935 | },
1936 | "principals": [
1937 | {
1938 | "identifiers": {
1939 | "constant_value": [
1940 | "eks.amazonaws.com",
1941 | ],
1942 | },
1943 | "type": {
1944 | "constant_value": "Service",
1945 | },
1946 | },
1947 | ],
1948 | },
1949 | ],
1950 | },
1951 | "count": {},
1952 | "depends_on": [],
1953 | "for_each": {},
1954 | "mode": "data",
1955 | "module_address": "",
1956 | "name": "iam_policy_eks",
1957 | "provider_config_key": "aws",
1958 | "provisioners": [],
1959 | "type": "aws_iam_policy_document",
1960 | },
1961 | "data.aws_iam_policy_document.policy": {
1962 | "address": "data.aws_iam_policy_document.policy",
1963 | "config": {
1964 | "statement": [
1965 | {
1966 | "actions": {
1967 | "constant_value": [
1968 | "es:*",
1969 | ],
1970 | },
1971 | "principals": [
1972 | {
1973 | "identifiers": {
1974 | "constant_value": [
1975 | "*",
1976 | ],
1977 | },
1978 | "type": {
1979 | "constant_value": "AWS",
1980 | },
1981 | },
1982 | ],
1983 | "resources": {
1984 | "constant_value": [
1985 | "*",
1986 | ],
1987 | },
1988 | },
1989 | ],
1990 | },
1991 | "count": {},
1992 | "depends_on": [],
1993 | "for_each": {},
1994 | "mode": "data",
1995 | "module_address": "",
1996 | "name": "policy",
1997 | "provider_config_key": "aws",
1998 | "provisioners": [],
1999 | "type": "aws_iam_policy_document",
2000 | },
2001 | "null_resource.push_image": {
2002 | "address": "null_resource.push_image",
2003 | "config": {},
2004 | "count": {},
2005 | "depends_on": [],
2006 | "for_each": {},
2007 | "mode": "managed",
2008 | "module_address": "",
2009 | "name": "push_image",
2010 | "provider_config_key": "null",
2011 | "provisioners": [
2012 | {
2013 | "config": {
2014 | "command": {
2015 | "references": [
2016 | "var.region",
2017 | "data.aws_caller_identity.current",
2018 | "var.region",
2019 | "aws_ecr_repository.repository",
2020 | "aws_ecr_repository.repository",
2021 | "local.docker_image",
2022 | "local.docker_image",
2023 | ],
2024 | },
2025 | "working_dir": {
2026 | "references": [
2027 | "path.module",
2028 | ],
2029 | },
2030 | },
2031 | "index": 0,
2032 | "resource_address": "null_resource.push_image",
2033 | "type": "local-exec",
2034 | },
2035 | ],
2036 | "type": "null_resource",
2037 | },
2038 | }
2039 |
2040 | provisioners = {
2041 | "null_resource.push_image:0": {
2042 | "config": {
2043 | "command": {
2044 | "references": [
2045 | "var.region",
2046 | "data.aws_caller_identity.current",
2047 | "var.region",
2048 | "aws_ecr_repository.repository",
2049 | "aws_ecr_repository.repository",
2050 | "local.docker_image",
2051 | "local.docker_image",
2052 | ],
2053 | },
2054 | "working_dir": {
2055 | "references": [
2056 | "path.module",
2057 | ],
2058 | },
2059 | },
2060 | "index": 0,
2061 | "resource_address": "null_resource.push_image",
2062 | "type": "local-exec",
2063 | },
2064 | }
2065 |
2066 | variables = {
2067 | "ami": {
2068 | "default": "ami-09a5b0b7edf08843d",
2069 | "description": "",
2070 | "module_address": "",
2071 | "name": "ami",
2072 | },
2073 | "availability_zone": {
2074 | "default": "us-west-2a",
2075 | "description": "",
2076 | "module_address": "",
2077 | "name": "availability_zone",
2078 | },
2079 | "availability_zone2": {
2080 | "default": "us-west-2b",
2081 | "description": "",
2082 | "module_address": "",
2083 | "name": "availability_zone2",
2084 | },
2085 | "company_name": {
2086 | "default": "acme",
2087 | "description": "",
2088 | "module_address": "",
2089 | "name": "company_name",
2090 | },
2091 | "dbname": {
2092 | "default": "db1",
2093 | "description": "Name of the Database",
2094 | "module_address": "",
2095 | "name": "dbname",
2096 | },
2097 | "environment": {
2098 | "default": "dev",
2099 | "description": "",
2100 | "module_address": "",
2101 | "name": "environment",
2102 | },
2103 | "neptune-dbname": {
2104 | "default": "neptunedb1",
2105 | "description": "Name of the Neptune graph database",
2106 | "module_address": "",
2107 | "name": "neptune-dbname",
2108 | },
2109 | "password": {
2110 | "default": "Aa1234321Bb",
2111 | "description": "Database password",
2112 | "module_address": "",
2113 | "name": "password",
2114 | },
2115 | "profile": {
2116 | "default": "default",
2117 | "description": "",
2118 | "module_address": "",
2119 | "name": "profile",
2120 | },
2121 | "region": {
2122 | "default": "us-west-2",
2123 | "description": "",
2124 | "module_address": "",
2125 | "name": "region",
2126 | },
2127 | }
2128 |
2129 | outputs = {
2130 | "db_app_public_dns": {
2131 | "depends_on": [],
2132 | "description": "DB Public DNS name",
2133 | "module_address": "",
2134 | "name": "db_app_public_dns",
2135 | "sensitive": false,
2136 | "value": {
2137 | "references": [
2138 | "aws_instance.db_app",
2139 | ],
2140 | },
2141 | },
2142 | "db_endpoint": {
2143 | "depends_on": [],
2144 | "description": "DB Endpoint",
2145 | "module_address": "",
2146 | "name": "db_endpoint",
2147 | "sensitive": false,
2148 | "value": {
2149 | "references": [
2150 | "aws_db_instance.default",
2151 | ],
2152 | },
2153 | },
2154 | "ec2_public_dns": {
2155 | "depends_on": [],
2156 | "description": "Web Host Public DNS name",
2157 | "module_address": "",
2158 | "name": "ec2_public_dns",
2159 | "sensitive": false,
2160 | "value": {
2161 | "references": [
2162 | "aws_instance.web_host",
2163 | ],
2164 | },
2165 | },
2166 | "endpoint": {
2167 | "depends_on": [],
2168 | "description": "",
2169 | "module_address": "",
2170 | "name": "endpoint",
2171 | "sensitive": false,
2172 | "value": {
2173 | "references": [
2174 | "aws_eks_cluster.eks_cluster",
2175 | ],
2176 | },
2177 | },
2178 | "kubeconfig-certificate-authority-data": {
2179 | "depends_on": [],
2180 | "description": "",
2181 | "module_address": "",
2182 | "name": "kubeconfig-certificate-authority-data",
2183 | "sensitive": false,
2184 | "value": {
2185 | "references": [
2186 | "aws_eks_cluster.eks_cluster",
2187 | ],
2188 | },
2189 | },
2190 | "public_subnet": {
2191 | "depends_on": [],
2192 | "description": "The ID of the Public subnet",
2193 | "module_address": "",
2194 | "name": "public_subnet",
2195 | "sensitive": false,
2196 | "value": {
2197 | "references": [
2198 | "aws_subnet.web_subnet",
2199 | ],
2200 | },
2201 | },
2202 | "public_subnet2": {
2203 | "depends_on": [],
2204 | "description": "The ID of the Public subnet",
2205 | "module_address": "",
2206 | "name": "public_subnet2",
2207 | "sensitive": false,
2208 | "value": {
2209 | "references": [
2210 | "aws_subnet.web_subnet2",
2211 | ],
2212 | },
2213 | },
2214 | "secret": {
2215 | "depends_on": [],
2216 | "description": "",
2217 | "module_address": "",
2218 | "name": "secret",
2219 | "sensitive": false,
2220 | "value": {
2221 | "references": [
2222 | "aws_iam_access_key.user",
2223 | ],
2224 | },
2225 | },
2226 | "username": {
2227 | "depends_on": [],
2228 | "description": "",
2229 | "module_address": "",
2230 | "name": "username",
2231 | "sensitive": false,
2232 | "value": {
2233 | "references": [
2234 | "aws_iam_user.user",
2235 | ],
2236 | },
2237 | },
2238 | "vpc_id": {
2239 | "depends_on": [],
2240 | "description": "The ID of the VPC",
2241 | "module_address": "",
2242 | "name": "vpc_id",
2243 | "sensitive": false,
2244 | "value": {
2245 | "references": [
2246 | "aws_vpc.web_vpc",
2247 | ],
2248 | },
2249 | },
2250 | }
2251 |
2252 | module_calls = {}
2253 |
2254 | strip_index = func(addr) {
2255 | s = strings.split(addr, ".")
2256 | for s as i, v {
2257 | s[i] = strings.split(v, "[")[0]
2258 | }
2259 |
2260 | return strings.join(s, ".")
2261 | }
2262 |
--------------------------------------------------------------------------------