├── .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 | --------------------------------------------------------------------------------