Skip to content

Commit

Permalink
adding script and dockerfile+acion
Browse files Browse the repository at this point in the history
  • Loading branch information
nolan committed Jul 10, 2024
1 parent e31ee46 commit dad0b98
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/publish-tf-state-docs-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Publish TF State Docs Image

on:
push:
branches:
- main

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/tf-state-docs

jobs:
build-latest:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU #emulation support with QEMU to be able to build against more platforms.
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the container to GitHub Container Registry using the latest tag
uses: docker/[email protected]
with:
context: .
file: Dockerfile
platforms: |
linux/amd64
linux/arm64
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
push: true
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM python:3.12
ADD . .

ENV REPO_NAME="toto"

#Install dependencies
RUN apt-get update
RUN apt-get install -y jq
RUN python -m pip install --upgrade pip
RUN pip install pyaml
RUN /install_terragrunt_tofu.sh 1.6.3

#Code execution
ENTRYPOINT [ "python", "gen-wiki.py", "config.yml", "output/", "$REPO_NAME" ]
58 changes: 58 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
resources:
aws_elasticache_replication_group:
header: ElastiCache clusters
attributes:
- primary_endpoint_address
- reader_endpoint_address
- id
aws_db_instance:
header: RDS databases
attributes:
- address
aws_rds_cluster:
header: Aurora clusters
attributes:
- endpoint
- reader_endpoint
- id
aws_sqs_queue:
header: SQS Queues
attributes:
- url
- id
aws_s3_bucket:
header: S3 buckets
attributes: []
aws_iam_role:
header: IAM role
attributes:
- arn
aws_iam_user:
header: IAM user
attributes:
- id
- arn
kubernetes_service_account:
header: Service Account
attributes:
- id
aws_ecr_repository:
header: ECR repository
attributes:
- repository_url
- mutable_url
aws_sns_topic:
header: SNS topic
attributes:
- name
aws_cloudfront_distribution:
header: Cloudfront
attributes:
- id
# kubernetes_secret:
# header: Secrets
# attributes:
kubernetes_config_map:
header: Config map
attributes:
- id
194 changes: 194 additions & 0 deletions gen-wiki.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import os
import re
import yaml
import json
import argparse
import subprocess
import shutil

TEMP_DIR = 'temp_wiki'

HOMEPAGE_CONTENT = """
# Welcome to {repo_name} terragrunt Wiki
## Introduction
Welcome to the official wiki for the **{repo_name}** project. Here you will find all the necessary documentation to understand and contribute to the project.
## Table of Contents
{toc}
"""

def load_config(config_file):
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
return config

def load_json(json_content):
return json.loads(json_content)

def remove_aws_provider_profile(file_name):
search_pattern = r'aws_profile\s*=\s*".*?"'
replace_pattern = 'aws_profile = ""'

with open(file_name, 'r') as file:
content = file.read()
new_content = re.sub(search_pattern, replace_pattern, content)
with open(file_name, 'w') as file:
file.write(new_content)

def extract_attributes(data, resource_type, attributes):
extracted_data = []
for resource in data.get('resources', []):
if resource.get('type') == resource_type:
for instance in resource.get('instances', []):
extracted_item = {}
if not attributes:
extracted_item['id'] = instance.get('attributes', {}).get('id')
for attr in attributes:
if attr:
extracted_item[attr] = instance.get('attributes', {}).get(attr)
extracted_data.append(extracted_item)
return extracted_data

def generate_markdown_table(header, data):
if not data:
return ""

headers = list(data[0].keys())
table = f"### {header}\n\n"
table += "| " + " | ".join(headers) + " |\n"
table += "| " + " | ".join(['---'] * len(headers)) + " |\n"

for item in data:
row = "| " + " | ".join(str(item.get(h, '')) for h in headers) + " |\n"
table += row

table += "\n"
return table

def run_terragrunt(directory):
try:
result = subprocess.run(['terragrunt', 'state', 'pull'], cwd=directory, check=True, capture_output=True, text=True)
print(f"Directory = ", directory)
return result.stdout
except subprocess.CalledProcessError as e:
return None

def process_directory(directory, config):
json_content = run_terragrunt(directory)
if not json_content:
return None

data = load_json(json_content)
markdown_content = ""

for resource_type, settings in config.get('resources', {}).items():
header = settings.get('header', resource_type)
attributes = settings.get('attributes', [])
extracted_data = extract_attributes(data, resource_type, attributes)
table = generate_markdown_table(header, extracted_data)
if table:
markdown_content += table

if markdown_content:
module_name = os.path.basename(directory)
markdown_content = f"## {module_name.capitalize()}\n\n" + markdown_content

return markdown_content

def process_environment(environment, config, output_dir):
markdown_content = f"# {environment.capitalize()} Environment\n\n"
for root, dirs, files in os.walk(environment):
if '.terragrunt-cache' in root:
continue

content = process_directory(root, config)
if content:
markdown_content += content

if markdown_content.strip() != f"# {environment.capitalize()} Environment\n\n":
output_file = os.path.join(output_dir, f"{environment}.md")
os.makedirs(output_dir, exist_ok=True)
with open(output_file, 'w') as f:
f.write(markdown_content)
print(f"Markdown file generated for {environment}: {output_file}")

def process_shared_ecr(shared_dir, config, output_dir):
ecr_dir = os.path.join(shared_dir, 'ecr')
if os.path.isdir(ecr_dir):
markdown_content = f"# Shared ECR\n\n"
content = process_directory(ecr_dir, config)
if content:
markdown_content += content
output_file = os.path.join(output_dir, 'ecr.md')
with open(output_file, 'w') as f:
f.write(markdown_content)
print(f"Markdown file generated for shared ECR: {output_file}")

def list_md_files(directory):
"""List all .md files in a given directory."""
md_files = []
for root, _, files in os.walk(directory):
for file in files:
if file.endswith('.md'):
md_files.append(os.path.join(root, file))
return md_files

def generate_sidebar_content(md_files):
"""Generate sidebar content from a list of markdown files."""
sidebar_content = "# Sidebar\n\n - [Home](home)\n"
for md_file in md_files:
filename = os.path.basename(md_file)
name, _ = os.path.splitext(filename)
sidebar_content += f"- [{name}]({name})\n"
return sidebar_content

def generate_homepage_content(repo_name, md_files):
"""Generate home page content from a list of markdown files."""
toc = ""
for md_file in md_files:
filename = os.path.basename(md_file)
name, _ = os.path.splitext(filename)
toc += f"- [{name}]({name})\n"
return HOMEPAGE_CONTENT.format(repo_name=repo_name, toc=toc)

def create_sidebar_and_homepage(temp_dir, repo_name, md_files):
"""Create a custom sidebar and a stylish home page."""
homepage_content = generate_homepage_content(repo_name, md_files)

with open(os.path.join(temp_dir, 'Home.md'), 'w', encoding='utf-8') as file:
file.write(homepage_content)

def copy_wiki(md_files):
for md_file in md_files:
subprocess.run(['cp', "terraform/live/" + md_file, 'temp_wiki'], check=True)

def clean_up_directory(directory_list):
os.chdir("..")
for directory in directory_list:
try:
shutil.rmtree(directory)
except Exception as e:
print(f"{e}")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Extract secrets using terragrunt state pull based on a YAML configuration.')
parser.add_argument('config_file', help='Path to the YAML configuration file')
parser.add_argument('output_dir', help='Path to the output directory')
parser.add_argument('repo_name', help='Name of the repo you want to create a doc for')
parser.add_argument('--environments', nargs='+', default=['development', 'production', 'test', 'staging'], help='Environments to process')
parser.add_argument('--shared_dir', default='shared', help='Directory for shared resources')

args = parser.parse_args()

config = load_config(args.config_file)
os.chdir("terraform/live")
remove_aws_provider_profile("terragrunt.hcl")
directories = [d for d in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), d))]
for directory in directories:
process_environment(directory, config, args.output_dir)

md_files = list_md_files(args.output_dir)
os.chdir("../..")
create_sidebar_and_homepage(TEMP_DIR, args.repo_name, md_files)
copy_wiki(md_files)
12 changes: 12 additions & 0 deletions install_terragrunt_tofu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh
TR_VERSION=`curl -s https://api.github.com/repos/gruntwork-io/terragrunt/releases/latest | jq -r .tag_name`
TOFU_VERSION=$1

wget -q "https://github.com/gruntwork-io/terragrunt/releases/download/${TR_VERSION}/terragrunt_linux_amd64"
# chmod +x terragrunt_linux_amd64
# sudo mv terragrunt_linux_amd64 /usr/local/bin/terragrunt

# sudo apt-get update && sudo apt-get install -y wget unzip
# wget -q -O tofu.zip https://github.com/opentofu/opentofu/releases/download/v${TOFU_VERSION}/tofu_${TOFU_VERSION}_linux_amd64.zip
# unzip -u tofu.zip
# sudo mv tofu /usr/local/bin/

0 comments on commit dad0b98

Please sign in to comment.