├── Dockerfile ├── README.md ├── entrypoint.sh └── main.py /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8.5-alpine3.12 2 | 3 | ENV DIRECTORY /tf 4 | 5 | VOLUME /tf 6 | 7 | COPY entrypoint.sh /entrypoint.sh 8 | COPY main.py /main.py 9 | 10 | ENTRYPOINT ["/entrypoint.sh"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tfmodvercheck 2 | 3 | This simple Python script will crawl your `modules.json` generated by `terraform init` command in order to verify that all modules are using the same version. 4 | 5 | It's main purpose is to be used within CI/CD pipeline. 6 | 7 | ## Usage 8 | 9 | ### Python script 10 | 11 | ```shell script 12 | python3 main.py PATH_TO_MODULES_JSON 13 | ``` 14 | 15 | ### Docker image 16 | 17 | Docker image can be used to verify multiple `module.json` files within a directory. 18 | 19 | ```shell script 20 | docker run --rm -it -v PATH_TO_YOUR_TERRAFORM_DIRECTORY:/tf docker.pkg.github.com/sysdogs/tfmodvercheck/tfmodvercheck:0.1.0 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find "${DIRECTORY}" -name 'modules.json' -exec sh -c 'python3 /main.py "$1"' _ {} \; -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | 4 | 5 | class Module(object): 6 | def __init__(self, key, source, version, module_dir): 7 | self.key = key 8 | self.source = source 9 | self.version = version 10 | self.dir = module_dir 11 | 12 | 13 | def main(): 14 | parser = argparse.ArgumentParser() 15 | parser.add_argument('path', type=str, help='path to modules.json') 16 | args = parser.parse_args() 17 | 18 | modules = [] 19 | 20 | with open(args.path) as stream: 21 | input_data = json.loads(stream.read()) 22 | 23 | for module in input_data['Modules']: 24 | if not all(key in module for key in ('Key', 'Source', 'Version', 'Dir')): 25 | continue 26 | 27 | modules.append(Module(module['Key'], module['Source'], module['Version'], module['Dir'])) 28 | 29 | sources = list(set([module.source for module in modules])) 30 | diverged = False 31 | 32 | for source in sources: 33 | same_source_modules = [module for module in modules if module.source == source] 34 | uniques = list({object_.version: object_ for object_ in same_source_modules}.values()) 35 | 36 | if len(uniques) > 1: 37 | diverged = True 38 | print('Diverged module version detected for module: {}'.format(source)) 39 | print('Resources:') 40 | 41 | for res in uniques: 42 | print('Directory: {}, key: {}, version: {}'.format(res.dir, res.key, res.version)) 43 | 44 | if diverged: 45 | exit(1) 46 | else: 47 | exit(0) 48 | 49 | 50 | main() 51 | --------------------------------------------------------------------------------