-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Add topics and improve descriptions for terraform_module repos #236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add topics variable to plain-repo module for repository
discoverability
- Set homepage_url to GitHub Pages URL for terraform_module repos
- Update all terraform_module repo descriptions with comprehensive
HEREDOC
descriptions based on actual README content
- Add auto-generated topics based on repo_type (terraform, aws,
python, etc.)
- Add per-repo specific topics for all 47 terraform_module
repositories
State
|
| Success | Add | 🟡 Change | 🔴 Destroy |
|---|---|---|---|
| ✅ | 0 | 65 | 26 |
Affected resources by action
| Action | Resources |
|---|---|
| 🟡 | module.repos["aws-control"].github_repository.repo |
| 🟡 | module.repos["aws-control-289256138624"].github_repository.repo |
| 🟡 | module.repos["aws-control-303467602807"].github_repository.repo |
| 🟡 | module.repos["aws-control-493370826424"].github_repository.repo |
| 🟡 | module.repos["cookiecutter-github-control"].github_repository.repo |
| 🟡 | module.repos["hiera-aws-sm"].github_repository.repo |
| 🟡 | module.repos["homebrew-infrahouse-toolkit"].github_repository.repo |
| 🟡 | module.repos["infrahouse-com"].github_repository.repo |
| 🟡 | module.repos["infrahouse-core"].github_repository.repo |
| 🟡 | module.repos["infrahouse-puppet-data"].github_repository.repo |
| 🟡 | module.repos["infrahouse-toolkit"].github_repository.repo |
| 🟡 | module.repos["infrahouse-ubuntu-pro"].github_repository.repo |
| 🟡 | module.repos["infrahouse-website-infra"].github_repository.repo |
| 🟡 | module.repos["osv-scanner"].github_repository.repo |
| 🟡 | module.repos["prometheus-elasticsearch-exporter"].github_repository.repo |
| 🟡 | module.repos["proxysql-sandbox"].github_repository.repo |
| 🟡 | module.repos["puppet-code"].github_repository.repo |
| 🟡 | module.repos["pytest-infrahouse"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-actions-runner"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-bookstack"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-ci-cd"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-cloud-init"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-cloudcraft-role"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-cost-alert"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-debian-repo"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-dms"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-ecr"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-ecs"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-elasticsearch"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-emrserverless"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-gh-identity-provider"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-gha-admin"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-github-backup"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-github-backup-configuration"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-github-role"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-guardduty-configuration"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-http-redirect"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-instance-profile"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-iso27001"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-jumphost"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-key"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-kibana"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-lambda-monitored"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-openvpn"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-percona-server"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-pmm-ecs"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-postfix"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-pypiserver"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-registry"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-s3-bucket"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-secret"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-secret-policy"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-service-network"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-sqs-ecs"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-sqs-pod"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-state-bucket"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-state-manager"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-tags-override"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-tcp-pod"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-teleport"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-teleport-agent"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-terraformer"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-truststore"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-update-dns"].github_repository.repo |
| 🟡 | module.repos["terraform-aws-website-pod"].github_repository.repo |
| 🔴 | module.repos["terraform-aws-aerospike"].github_actions_secret.anthropic_api_key[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_branch_default.main |
| 🔴 | module.repos["terraform-aws-aerospike"].github_branch_protection.main[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository.repo |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.claude_instructions |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.cliff_config[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.coding_standard |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.commit_msg_hook[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.contributing_md[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.docs_index[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.docs_workflow[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.license[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.makefile_example[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.mkdocs_config[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.pre_commit_hook[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.release_workflow[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.renovate_json |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.review_local_command[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.security_md[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.terraform_docs_config[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.terraform_module_reviewer[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.terraform_review_workflow[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_file.vuln_scanner_workflow |
| 🔴 | module.repos["terraform-aws-aerospike"].github_repository_ruleset.main[0] |
| 🔴 | module.repos["terraform-aws-aerospike"].github_team_repository.admin |
| 🔴 | module.repos["terraform-aws-aerospike"].github_team_repository.dev |
STDOUT
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
~ update in-place
- destroy
Terraform will perform the following actions:
# module.repos["aws-control"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "aws-control"
name = "aws-control"
~ topics = [
+ "aws",
+ "infrahouse",
+ "terraform",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["aws-control-289256138624"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "aws-control-289256138624"
name = "aws-control-289256138624"
~ topics = [
+ "aws",
+ "infrahouse",
+ "terraform",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["aws-control-303467602807"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "aws-control-303467602807"
name = "aws-control-303467602807"
~ topics = [
+ "aws",
+ "infrahouse",
+ "terraform",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["aws-control-493370826424"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "aws-control-493370826424"
name = "aws-control-493370826424"
~ topics = [
+ "aws",
+ "infrahouse",
+ "terraform",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["cookiecutter-github-control"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "cookiecutter-github-control"
name = "cookiecutter-github-control"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["hiera-aws-sm"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "hiera-aws-sm"
name = "hiera-aws-sm"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["homebrew-infrahouse-toolkit"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "homebrew-infrahouse-toolkit"
name = "homebrew-infrahouse-toolkit"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["infrahouse-com"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "infrahouse-com"
name = "infrahouse-com"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
}
# module.repos["infrahouse-core"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Python library for AWS infrastructure automation - EC2 instance management, DynamoDB distributed locks, Route53 DNS, Secrets Manager - with cross-account role assumption and GitHub Actions self-hosted runner integration" -> "Python library for AWS infrastructure automation - EC2 instance management, DynamoDB distributed locks, Route53 DNS, Secrets Manager - with cross-account role assumption and GitHub Actions self-hosted runner integration "
id = "infrahouse-core"
name = "infrahouse-core"
~ topics = [
+ "infrahouse",
+ "python",
]
# (33 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["infrahouse-puppet-data"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "infrahouse-puppet-data"
name = "infrahouse-puppet-data"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["infrahouse-toolkit"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "infrahouse-toolkit"
name = "infrahouse-toolkit"
~ topics = [
+ "infrahouse",
+ "python",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["infrahouse-ubuntu-pro"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "infrahouse-ubuntu-pro"
name = "infrahouse-ubuntu-pro"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["infrahouse-website-infra"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "infrahouse-website-infra"
name = "infrahouse-website-infra"
~ topics = [
+ "aws",
+ "infrahouse",
+ "terraform",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["osv-scanner"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "osv-scanner"
name = "osv-scanner"
~ topics = [
+ "infrahouse",
]
# (35 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["prometheus-elasticsearch-exporter"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "prometheus-elasticsearch-exporter"
name = "prometheus-elasticsearch-exporter"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["proxysql-sandbox"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "proxysql-sandbox"
name = "proxysql-sandbox"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["puppet-code"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "puppet-code"
name = "puppet-code"
~ topics = [
+ "infrahouse",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["pytest-infrahouse"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
id = "pytest-infrahouse"
name = "pytest-infrahouse"
~ topics = [
+ "infrahouse",
+ "python",
]
# (34 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.repos["terraform-aws-actions-runner"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that deploys self-hosted GitHub Actions runner." -> "Terraform module for self-hosted GitHub Actions runners on AWS EC2 with auto-scaling, Puppet configuration management, CloudWatch monitoring, and automatic runner registration/deregistration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-actions-runner"
id = "terraform-aws-actions-runner"
name = "terraform-aws-actions-runner"
~ topics = [
+ "aws",
+ "ci-cd",
+ "github",
+ "github-actions",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-aerospike"].github_actions_secret.anthropic_api_key[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_actions_secret" "anthropic_api_key" {
- created_at = "2025-11-27 23:20:24 +0000 UTC" -> null
- id = "terraform-aws-aerospike:ANTHROPIC_API_KEY" -> null
- plaintext_value = (sensitive value) -> null
- repository = "terraform-aws-aerospike" -> null
- secret_name = "ANTHROPIC_API_KEY" -> null
- updated_at = "2025-11-27 23:20:24 +0000 UTC" -> null
# (1 unchanged attribute hidden)
}
# module.repos["terraform-aws-aerospike"].github_branch_default.main will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_branch_default" "main" {
- branch = "main" -> null
- etag = "W/\"6b7aa1c2c2c605c4a7f1e0997a260eb8df6ac38acee5943646ff62beb97fd351\"" -> null
- id = "terraform-aws-aerospike" -> null
- rename = false -> null
- repository = "terraform-aws-aerospike" -> null
}
# module.repos["terraform-aws-aerospike"].github_branch_protection.main[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_branch_protection" "main" {
- allows_deletions = false -> null
- allows_force_pushes = false -> null
- enforce_admins = false -> null
- force_push_bypassers = [] -> null
- id = "BPR_kwDOLhBFc84EB7Jm" -> null
- lock_branch = false -> null
- pattern = "main" -> null
- repository_id = "R_kgDOLhBFcw" -> null
- require_conversation_resolution = false -> null
- require_signed_commits = false -> null
- required_linear_history = false -> null
- required_pull_request_reviews {
- dismiss_stale_reviews = true -> null
- dismissal_restrictions = [] -> null
- pull_request_bypassers = [
- "A_kwHOB0VVB84AD4Ir",
] -> null
- require_code_owner_reviews = true -> null
- require_last_push_approval = false -> null
- required_approving_review_count = 1 -> null
- restrict_dismissals = false -> null
}
}
# module.repos["terraform-aws-aerospike"].github_repository.repo will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository" "repo" {
- allow_auto_merge = false -> null
- allow_merge_commit = true -> null
- allow_rebase_merge = true -> null
- allow_squash_merge = true -> null
- allow_update_branch = false -> null
- archived = false -> null
- default_branch = "main" -> null
- delete_branch_on_merge = true -> null
- description = "Module that deploys Aerospike cluster." -> null
- etag = "W/\"6b7aa1c2c2c605c4a7f1e0997a260eb8df6ac38acee5943646ff62beb97fd351\"" -> null
- full_name = "infrahouse/terraform-aws-aerospike" -> null
- git_clone_url = "git://github.com/infrahouse/terraform-aws-aerospike.git" -> null
- has_discussions = false -> null
- has_downloads = false -> null
- has_issues = true -> null
- has_projects = true -> null
- has_wiki = false -> null
- html_url = "https://github.com/infrahouse/terraform-aws-aerospike" -> null
- http_clone_url = "https://github.com/infrahouse/terraform-aws-aerospike.git" -> null
- id = "terraform-aws-aerospike" -> null
- is_template = false -> null
- merge_commit_message = "PR_TITLE" -> null
- merge_commit_title = "MERGE_MESSAGE" -> null
- name = "terraform-aws-aerospike" -> null
- node_id = "R_kgDOLhBFcw" -> null
- primary_language = "Shell" -> null
- private = false -> null
- repo_id = 772818291 -> null
- squash_merge_commit_message = "COMMIT_MESSAGES" -> null
- squash_merge_commit_title = "COMMIT_OR_PR_TITLE" -> null
- ssh_clone_url = "git@github.com:infrahouse/terraform-aws-aerospike.git" -> null
- svn_url = "https://github.com/infrahouse/terraform-aws-aerospike" -> null
- topics = [] -> null
- visibility = "public" -> null
- vulnerability_alerts = true -> null
- web_commit_signoff_required = false -> null
# (1 unchanged attribute hidden)
- pages {
- build_type = "workflow" -> null
- custom_404 = false -> null
- html_url = "https://infrahouse.github.io/terraform-aws-aerospike/" -> null
- url = "https://api.github.com/repos/infrahouse/terraform-aws-aerospike/pages" -> null
# (2 unchanged attributes hidden)
}
- security_and_analysis {
- secret_scanning {
- status = "disabled" -> null
}
- secret_scanning_push_protection {
- status = "disabled" -> null
}
}
}
# module.repos["terraform-aws-aerospike"].github_repository_file.claude_instructions will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "claude_instructions" {
- commit_message = "Add Claude Code instructions" -> null
- commit_sha = "88e9ccdddfcd4ba938ecb62879692ffa90592965" -> null
- content = <<-EOT
# Project Instructions for Claude Code
## Terraform Coding Standards
**ALWAYS read and follow `.claude/CODING_STANDARD.md` before writing or modifying any Terraform code.**
This file contains critical requirements including:
- Proper use of ternary operators vs logical OR in validation blocks with nullable variables
- Tagging conventions
- Provider requirements
- Module pinning
- IAM policy patterns
Pay special attention to validation blocks - they require ternary operators to avoid null comparison errors.
EOT -> null
- file = "./.claude/instructions.md" -> null
- id = "terraform-aws-aerospike/./.claude/instructions.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "f862fa15b5bb87752da1b41739ef94bae7db9601" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.cliff_config[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "cliff_config" {
- commit_message = "Add cliff.toml configuration" -> null
- commit_sha = "e3c2939fe437fb9b973d2a1b16d657c54c425f00" -> null
- content = <<-EOT
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
# git-cliff configuration file
# https://git-cliff.org/docs/configuration
[changelog]
# changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}\n
"""
# remove the leading and trailing whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""
[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = true
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for preprocessing the commit messages
commit_preprocessors = [
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/infrahouse/terraform-aws-aerospike/issues/${2}))"}, # link to issue
]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^doc", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^refactor", group = "Refactor"},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore\\(release\\): prepare for", skip = true},
{ message = "^chore", group = "Miscellaneous Tasks"},
{ body = ".*security", group = "Security"},
]
# protect breaking changes from being skipped due to matching a skipping commit_parser
protect_breaking_commits = false
# filter out the commits that are not matched by commit parsers
filter_commits = false
# glob pattern for matching git tags
tag_pattern = "v?[0-9]*"
# regex for skipping tags
skip_tags = ""
# regex for ignoring tags
ignore_tags = ""
# sort the tags topologically
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "oldest"
EOT -> null
- file = "./cliff.toml" -> null
- id = "terraform-aws-aerospike/./cliff.toml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "19b2000462ecc6c08e635bdc812ed20df6c0a936" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.coding_standard will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "coding_standard" {
- commit_message = "Add CODING_STANDARD.md" -> null
- commit_sha = "5fd860cdea31e04d47967bfd6afed6dec5e68056" -> null
- content = <<-EOT
<!--
This file is managed by Terraform in github-control repository
Do not edit this file, all changes will be overwritten
If you need to change this file, create a pull request in
https://github.com/infrahouse8/github-control
-->
# Coding Standards
This document defines coding standards for InfraHouse projects.
## General Formatting (All Files)
* **Maximum line length: 120 characters**
- Applies to all files: code (Python, Terraform, Puppet), documentation (Markdown, plans), configuration files, etc.
- Break long lines for readability
- Exception: URLs or other content that cannot be split
* **All files must end with a newline character**
## Python Standards
### Code Formatting
* **Use Black for code formatting**
- Format code: `black .`
- Check formatting in CI: `black --check .`
- Black is the uncompromising Python code formatter
- Ensures consistent formatting across all projects
### Linting
* **Use pylint for code linting**
- Enforces code quality standards
- Run: `pylint <module_name>`
- Configuration: `.pylintrc` in project root
### Type Hinting
* **Type hints are required for all functions**
- Include type hints for all function parameters and return values
- Use standard library `typing` module
- Example:
```python
from typing import List, Dict, Optional
def process_items(items: List[str], config: Optional[Dict[str, str]] = None) -> bool:
"""
Process a list of items with optional configuration.
:param items: List of item names to process
:param config: Optional configuration dictionary
:return: True if processing succeeded
"""
# Implementation
return True
```
### Documentation
* **Use RST (reStructuredText) docstrings** for all functions, classes, and modules
- Follow Sphinx docstring format
- Include parameter descriptions, return values, and exceptions
### Testing
* **Use pytest for all tests**
- Tests must be meaningful and test specific behaviors
- **Cover both happy and unhappy paths**
- No coverage requirements (quality over quantity)
- Don't write tests just to achieve coverage percentage
- Example:
```python
def test_function_success():
"""Test the happy path - function succeeds with valid input."""
result = my_function("valid_input")
assert result == expected_output
def test_function_invalid_input():
"""Test the unhappy path - function fails gracefully with invalid input."""
with pytest.raises(ValueError) as exc_info:
my_function("invalid_input")
assert "expected error message" in str(exc_info.value)
```
### Error Handling
* **Never use bare `except Exception:`**
- It's better to crash than to mute an error silently
- Only catch specific exceptions you can actually handle
- If you catch an exception, either fix the problem or re-raise it
- Example:
```python
# WRONG - mutes all errors:
try:
risky_operation()
except Exception:
pass # Don't do this
# CORRECT - catch specific exceptions:
try:
risky_operation()
except FileNotFoundError as e:
logger.error(f"Required file not found: {e}")
raise # Re-raise if you can't fix the problem
except ValueError as e:
# Fix the problem if you can handle it
return default_value
```
### Logging
* **Use `setup_logging()` from infrahouse-core**
- Provides consistent logging configuration across projects
- Example:
```python
from infrahouse_core.logging import setup_logging
LOG = setup_logging(__name__)
def my_function():
LOG.info("Starting operation")
LOG.debug("Debug details here")
LOG.error("Error occurred")
```
### Dependencies
* Pin Python dependencies to a major version. Use ~= syntax. I.e. `requests ~= 2.31` instead of `requests>=2.31.0,<3.0.0`
- Trusts semantic versioning for patch and minor updates
- Libraries (like infrahouse-core) require version ranges; exact versions cause dependency conflicts
- Applications benefit from automatic security/bug fixes while unit tests provide safety
### InfraHouse Packages
* **infrahouse-core** (https://pypi.org/project/infrahouse-core/)
- Library with reusable classes and functions
- Use for imports in your Python code
- Examples: AWS helper classes, validation utilities, `setup_logging()` function
- When creating reusable code, add it to infrahouse-core
* **infrahouse-toolkit** (https://pypi.org/project/infrahouse-toolkit/)
- End-user CLI toolkit for provisioning, operational tasks, and CI/CD workflows
- Use as command-line tool (not for imports)
- Depends on infrahouse-core
- Note: Some classes exist in infrahouse-toolkit for historical reasons; reusable classes should migrate to
infrahouse-core
* **pytest-infrahouse** (https://pypi.org/project/pytest-infrahouse/)
- Pytest fixtures for Terraform module testing
- Provides fixtures for AWS infrastructure testing
- Use in test files with pytest
## Terraform Standards
### General
* When a variable or output description is too long, use HEREDOC construction to wrap lines
```hcl
variable "vpc_cidr" {
type = string
description = <<-EOT
The CIDR block for the VPC. Must be a valid IPv4 CIDR block.
Should not overlap with other VPCs or on-premises networks.
Recommended ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
EOT
}
```
* The module should only require providers it actually uses to create direct resources.
Child modules should take care of their required providers
- Separation of concerns: each module knows which providers it needs
- A module shouldn't dictate provider requirements for resources it doesn't directly create
* **InfraHouse modules must use registry.infrahouse.com** (private but publicly available registry)
* **All modules must use exact version pinning** (no ranges)
- Makes only one infrastructure change at a time (your change, not unrelated module updates)
- Version ranges are dangerous: unrelated updates can trigger risky operations
(e.g., adding a secret shouldn't trigger ElasticSearch instance refresh)
- Renovate manages version updates via individual PRs for explicit review and testing
```hcl
# InfraHouse modules - use registry.infrahouse.com:
module "vpc" {
source = "registry.infrahouse.com/infrahouse/service-network/aws"
version = "3.2.1" # Always exact version
# ...
}
# Non-InfraHouse modules - also exact version:
module "external" {
source = "terraform-aws-modules/vpc/aws"
version = "5.1.2" # Always exact version
# ...
}
# WRONG - version range (applies to any module):
module "bad" {
source = "..."
version = "~> 3.2" # Don't do this
# ...
}
```
### Naming Conventions
* **Use snake_case everywhere**: Variables, resources, data sources, locals, outputs
- Use underscores (`_`), not dashes (`-`)
- Use lowercase letters and numbers only
* **Variable naming:**
- Boolean variables with verbs: `enable_*` or `create_*` (e.g., `enable_monitoring`, `create_bucket`)
- Boolean variables with nouns: `is_*` (e.g., `is_public`, `is_encrypted`)
- Lists: use plural form (e.g., `subnet_ids`, `availability_zones`)
* **Resource naming:**
- Single resource of a type: use `this` or `main` (e.g., `aws_nat_gateway.this`)
- Multiple resources of same type: use descriptive names (e.g., `aws_route_table.private`,
`aws_route_table.public`)
- Don't include resource type in name (GOOD: `aws_instance.web`, BAD: `aws_instance.ec2_web`)
* **Locals naming:**
- Use descriptive snake_case names
* **Output naming:**
- Group related outputs with prefixes (e.g., `vpc_id`, `vpc_cidr`, `vpc_arn`)
### Variables
* **Always specify explicit type constraints**
- Use `type = string`, `type = number`, `type = list(string)`, etc.
- Don't rely on Terraform's type inference
* **Default values - when to use:**
- **Required (no default)**: Critical for compliance/governance (e.g., `alert_emails`), no sensible default exists
(e.g., `environment`, `service`), need to force explicit user decision
- **Optional (with default)**: Meaningful, recommended default exists (e.g., `instance_type = "t3.micro"` for
specific workload)
- **Never default**: Arbitrary/meaningless values (e.g., `environment = "dev"`, `managed_by = "terraform"`)
* **Validation:**
- Goal: Catch definitely wrong input values, not enforce arbitrary constraints
- Add validation for: Format checks (CIDR, email), range checks (percentages 0-100, non-negative values)
- Error messages must: Explain what's wrong with specifics, include instructions on how to fix
- Use appropriate methods: Regex for formats, range checks, contains() for valid sets
- Don't enforce arbitrary lists (like approved instance types) unless there's a strong reason
* **Sensitive variables:**
- Always mark as `sensitive = true`
- Use `infrahouse/secret/aws` module for secrets management
- Specify allowed readers in the `readers` input value
- Never put secret values in user data; pass secret name/ARN instead
* **Complete variable examples:**
```hcl
# Example 1: Required variable with validation
variable "environment" {
type = string
description = "Environment name (development, staging, production, etc.)"
validation {
condition = can(regex("^[a-z0-9_]+$", var.environment))
error_message = "environment must contain only lowercase letters, numbers, and underscores (no hyphens)"
}
}
# Example 2: Optional variable with meaningful default
variable "instance_type" {
type = string
description = "EC2 instance type for the application servers"
default = "t3.micro"
}
# Example 3: Complex variable with all elements
variable "max_instance_count" {
type = number
description = <<-EOT
Maximum number of instances in the Auto Scaling Group.
Must be between 1 and 100. Set to null to use the recommended default based on workload.
EOT
default = null
validation {
condition = var.max_instance_count == null ? true : (var.max_instance_count >= 1 && var.max_instance_count <= 100)
error_message = "max_instance_count must be between 1 and 100, or null. Got: ${var.max_instance_count}"
}
}
# Example 4: Sensitive variable (receives secret value from infrahouse/secret/aws module)
variable "database_password" {
type = string
description = "Database password value (from module.my_secret.secret_value)"
sensitive = true
}
# WRONG - never hardcode secrets:
variable "bad_password" {
type = string
description = "Database password"
default = "MyP@ssw0rd123" # NEVER DO THIS
sensitive = true
}
```
### Outputs
* **When to create outputs:**
- Use reasonable judgment: output values with high chance to be needed by another module
- Better to under-do than over-do - don't output everything "just in case"
* **Always provide descriptions** for all outputs
* **Sensitive outputs:**
- Mark as `sensitive = true` when they contain secrets or sensitive data
### Documentation
* **Inline comments:**
- Add comments to explain why, not what
- Document non-obvious decisions and reasoning
* **README.md (required):**
- Must include terraform-docs markers: `<!-- BEGIN_TF_DOCS -->` and `<!-- END_TF_DOCS -->`
- Pre-commit hook uses terraform-docs to auto-generate documentation
- **Required badges** (in this order):
- Contact: `[](https://infrahouse.com/contact)`
- Documentation: `[](https://infrahouse.github.io/repo-name/)`
- Terraform Registry: `[](https://registry.terraform.io/modules/infrahouse/module-name/aws/latest)`
- Latest Release: `[](https://github.com/infrahouse/repo-name/releases/latest)`
- AWS Service Badge(s): `[](https://aws.amazon.com/ec2/)` (link to relevant AWS service(s))
- Security: `[](https://github.com/infrahouse/repo-name/actions/workflows/vuln-scanner-pr.yml)`
- License: `[](LICENSE)`
- **Required sections:**
1. Brief description (what it does, why it exists)
2. Features (bullet list)
3. Quick Start (minimal working example)
4. Documentation (links to GitHub Pages)
5. Requirements (Terraform version, providers)
6. Usage (terraform-docs auto-generated)
7. Examples (link to examples/)
8. Contributing (link to CONTRIBUTING.md)
9. License (link to LICENSE)
* **examples/ directory:**
- Desired but optional
- Provide working examples when included
* **terraform-docs configuration:**
- `.terraform-docs.yml` is managed by github-control
- README.md uses centrally-managed configuration
### GitHub Pages Documentation (terraform_module)
* **Deployment:** Automated via `.github/workflows/docs.yml` (managed by github-control)
* **Built with:** MkDocs with Material theme
* **Required pages:**
- `docs/index.md` - Overview, features, quick start
- `docs/getting-started.md` - Prerequisites, first deployment
- `docs/configuration.md` - All variables explained with examples
* **Recommended pages:**
- `docs/architecture.md` - How it works, diagrams
- `docs/examples.md` - Common use cases with explanations
- `docs/troubleshooting.md` - Common issues and solutions
- `docs/changelog.md` - Or link to CHANGELOG.md
* **Optional pages:**
- `docs/comparison.md` - vs alternatives
- `docs/security.md` - Security considerations
- `docs/monitoring.md` - Observability setup
- `docs/upgrading.md` - Migration guides between versions
### Repository Files
* **Must have:**
- `README.md` - Module documentation (see above)
- `LICENSE` - Apache 2.0 (recommended for patent protection and enterprise adoption)
- `CHANGELOG.md` - Auto-generated with git-cliff
- `.terraform-docs.yml` - Managed by github-control
- `mkdocs.yml` - MkDocs configuration (managed by github-control)
- `cliff.toml` - git-cliff configuration (managed by github-control)
- `.github/workflows/release.yml` - Auto-create GitHub Releases from tags (managed by github-control)
- `examples/` directory - Working examples
* **Should have:**
- `CONTRIBUTING.md` - Contribution guidelines
- `SECURITY.md` - Security policy, how to report vulnerabilities
- `CODEOWNERS` - Auto-assign reviewers
- `.github/ISSUE_TEMPLATE/` - Bug report, feature request templates
- `.github/PULL_REQUEST_TEMPLATE.md` - PR template
### Release Automation
* **Automated via `.github/workflows/release.yml`** (managed by github-control)
* **Trigger:** Push of version tags (e.g., `0.1.0`, `v1.0.0`)
* **Process:**
1. git-cliff generates changelog for the release
2. GitHub Release is created automatically with release notes
3. "Latest Release" badge in README reflects the new version
* **Manual release process** (via Makefile targets):
```makefile
release-patch:
git-cliff --tag $(shell bumpversion --dry-run --list patch | grep new_version | cut -d= -f2) -o CHANGELOG.md
bumpversion patch
git push && git push --tags
# GitHub Actions workflow automatically creates the release
```
* **Available targets:** `release-patch`, `release-minor`, `release-major`
### Resource Organization
* **`count` vs `for_each`:**
- Use `count` for simple create/don't create scenarios (e.g., `count = var.enable_feature ? 1 : 0`)
- Use `for_each` for pre-calculated values (lists, sets, maps) - handles computed values better and avoids
index-shifting issues
* **`locals`:**
- Extract expressions to locals to make code readable and troubleshoot-able
- Follow usual programming best practices (DRY, meaningful names, avoid complex inline expressions)
* **File organization:**
- Always create at minimum: `main.tf`, `variables.tf`, `outputs.tf`
- Create additional files to break module into logical pieces by function (e.g., `iam.tf`, `networking.tf`)
- Don't inflate `main.tf` - split into focused files
* **Dependencies:**
- Prefer implicit dependencies (Terraform references)
- Use explicit `depends_on` only when Terraform struggles with ordering (usually as a bugfix)
- Acceptable to create indirect dependencies (e.g., use module output as tag value or resource name)
### Security
#### General Principles
* Follow principle of least privilege
* Comply with ISO27001 and SOC2 requirements
* Use AWS Control Tower for account governance
#### Secrets Management
* **Always use `infrahouse/secret/aws` module** for secrets storage
- Provides secure access control
- Enables auditing: "who has access to this secret?"
- See: https://infrahouse.com/blog/2024-09-29-compliant-secrets/
* Never hardcode secret values in code or user data
* Pass secret names/ARNs instead of values
#### Security Groups
* Avoid `0.0.0.0/0` for ingress rules (except specific cases like public ALBs)
* Prefer security group references over CIDR ranges for internal communication
- Example: Put ALB and ASG in same security group, allow inter-security-group traffic
* **ICMP rules:**
- Within VPC: Allow all ICMP types (for troubleshooting)
- From internet (0.0.0.0/0): Allow only types 3 (Destination Unreachable), 8 (Echo Request), 0 (Echo Reply),
11 (Time Exceeded). Block all other types
#### Encryption at Rest
* Enable encryption by default for all resources (S3, EBS, RDS, etc.)
* Use AWS-managed keys (SSE-S3, aws/ebs, etc.) by default
* **Exception - CloudTrail**: Must use Customer-Managed Keys (CMK)
* **S3 buckets**: Use `infrahouse/s3-bucket/aws` module - configures encryption per ISO/SOC requirements
#### Encryption in Transit
* **Require HTTPS/TLS** for all load balancers and APIs
* Allow HTTP only to redirect to HTTPS
* **TLS Policy for ALB:**
- Default: `ELBSecurityPolicy-TLS13-1-2-Res-2021-06` (Restrictive)
- Allowed: `ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06` (if compatibility required) or more restrictive policies
- Do not allow weaker/older policies
#### Logging and Auditing
* **Standard log retention**: 365 days (ISO requirement)
* **CloudTrail:**
- Must be enabled via Control Tower
- Must be encrypted with CMK
- Minimum retention: 365 days
* **VPC Flow Logs:**
- Always enable for all VPCs
- Destination: S3
- Retention: 365 days
- Use `infrahouse/service-network/aws` module for configuration
* **Application Logs:**
- Use CloudWatch Logs
- AWS-managed keys
- Retention: 365 days
* **AWS Config:**
- Required for ISO/SOC compliance
- Use default conformance packs
### Validation Blocks
* **CRITICAL: Always use ternary operators instead of logical OR when dealing with nullable variables.**
Terraform's OR operator doesn't properly short-circuit null comparisons, causing validation errors.
```hcl
# WRONG - will fail if var.value is null:
condition = var.value == null || var.value <= 100
# CORRECT - use ternary:
condition = var.value == null ? true : var.value <= 100
```
* **Additional validation patterns:**
```hcl
# Puppet environment name validation (lowercase letters, numbers, underscores only):
variable "environment" {
type = string
description = "Environment name (must follow Puppet naming rules)"
validation {
condition = can(regex("^[a-z0-9_]+$", var.environment))
error_message = "environment must contain only lowercase letters, numbers, and underscores (no hyphens). Got: ${var.environment}"
}
}
# Format validation (CIDR block):
variable "vpc_cidr" {
type = string
description = "The CIDR block for the VPC"
validation {
condition = can(cidrhost(var.vpc_cidr, 0))
error_message = "vpc_cidr must be a valid IPv4 CIDR block (e.g., 10.0.0.0/16)"
}
}
# Range validation (percentage):
variable "cpu_threshold" {
type = number
description = "CPU threshold percentage for alerting"
default = 80
validation {
condition = var.cpu_threshold >= 0 && var.cpu_threshold <= 100
error_message = "cpu_threshold must be between 0 and 100. Got: ${var.cpu_threshold}"
}
}
# List validation (minimum length):
variable "availability_zones" {
type = list(string)
description = "List of availability zones"
validation {
condition = length(var.availability_zones) >= 2
error_message = "At least 2 availability zones required for HA. Provided: ${length(var.availability_zones)}"
}
}
# Complex validation (nullable with additional check):
variable "max_size" {
type = number
description = "Maximum instance count"
default = null
validation {
condition = var.max_size == null ? true : (var.max_size > 0 && var.max_size <= 100)
error_message = "max_size must be between 1 and 100, or null. Got: ${var.max_size}"
}
}
```
### IAM Policies
* For IAM policies, use data source policy document, don't use a generated json
- Data sources handle policy versioning and formatting correctly
- User-generated JSON can fail with wrong version or formatting issues
- Delegates policy generation to Terraform, which does a better job than manual JSON
```hcl
# CORRECT - use data source:
data "aws_iam_policy_document" "lambda_assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "lambda" {
name = "lambda-role"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
# WRONG - generated JSON string:
resource "aws_iam_role" "lambda" {
name = "lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}
```
### Tagging
* Use lowercase tags except `Name`
- AWS tags are case-sensitive (`environment` ≠ `Environment`), so lowercase prevents confusion and accidental duplicates
- `Name` is capitalized to follow AWS console convention (displayed in resource tables)
- Note: AWS-generated tags (prefixed with `aws:`) are managed by AWS and ignored by this standard
* Use underscores for multi-word tags (e.g., `created_by_module`, not `created-by-module`)
* **Resource provenance tags** - Track what created each resource:
- `created_by`: GitHub repository that deployed the resource (format: `org/repo_name`)
Example: `"infrahouse/aws-control-289256138624"`
- `created_by_module`: Terraform module where resource is defined (format: `org/module_name/provider`)
Example: `"infrahouse/jumphost/aws"`
- `created_by_fixture`: Pytest fixture that created test resources (format: `org/package/fixture`)
Example: `"infrahouse/pytest-infrahouse/postgres"` (only present on test resources)
* Create one selected "main" resource with `module_version` tag
* **Require environment tag from user** - Do not provide defaults
- Prevents nonsense like `environment=dev` in production AWS accounts
- Forces explicit environment declaration, bringing order and preventing deployment mistakes
```hcl
# Example of proper tagging on a resource:
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t3.micro"
tags = {
Name = "web-server" # Capitalized per AWS convention
environment = var.environment # Required from user
service = var.service # Required from user
created_by = "infrahouse/aws-control-289256138624"
created_by_module = "infrahouse/ec2-instance/aws"
module_version = var.module_version # On selected "main" resource only
}
}
```
### Testing
#### Testing Philosophy
* Tests are called "unit tests" but are actually **integration tests**
- Create real infrastructure in AWS
- Validate the infrastructure behaves correctly
- Clean up resources after testing
#### Testing Framework
* Use **pytest** for all Terraform module tests
* Use Terraform fixtures from **pytest-infrahouse** (https://pypi.org/project/pytest-infrahouse/)
* Use **infrahouse-core** (https://pypi.org/project/infrahouse-core/) for validation
- Provides AWS and infrastructure helper classes
#### Test Coverage Requirements
* Must test **two AWS provider versions** at all times (currently versions 5 and 6)
* Test both happy path and edge cases
* Validate resource creation, outputs, and behavior
#### Makefile Requirements
* Implement **test-keep** and **test-clean** targets
* Support configurable test parameters:
```makefile
TEST_REGION ?= us-west-2
TEST_ROLE ?= arn:aws:iam::303467602807:role/ecs-tester
TEST_SELECTOR ?= tests/
TEST_PATH ?= tests/test_httpd.py
TEST_FILTER ?= "test_ and aws-6"
```
* `test-keep`: Run tests and keep infrastructure for debugging
* `test-clean`: Run tests and clean up all resources (use before PRs)
#### Development Workflow
1. **Local development**: Run tests with `test-keep` during feature development
2. **Before PR**: Run `make test-clean` for final validation
3. **Create PR**: GitHub Actions runs full test suite
4. **Merge**: When all tests pass
#### CI/CD Requirements
* The root module must define variables in terraform.tfvars
```hcl
# Example terraform.tfvars for testing:
environment = "development"
service = "my-service"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["us-west-2a", "us-west-2b"]
instance_type = "t3.micro"
enable_monitoring = true
```
* **Test root module must set `created_by` tag** in provider default_tags:
```hcl
provider "aws" {
default_tags {
tags = {
created_by = "infrahouse/terraform-aws-ecs" # GitHub repository that created the resource
}
}
}
```
* GitHub Actions must run on self-hosted runner (GitHub runners don't have ih-registry command)
* Test role session time in CI: **12 hours**
* .github/workflows/terraform-CD.yml configures CI test execution
## Puppet Standards
### General
* TBD - Standards to be documented
## Makefile Standards
All InfraHouse projects (Python libraries, Terraform modules, etc.) must include a Makefile following these standards.
### Help Target (Default)
* **`make help` must be the default target**
- Running `make` without arguments should display help
- Help output should list all user-facing targets with descriptions
- Implementation: Use `.DEFAULT_GOAL := help` or list `help` as first target
### Required Targets
#### `bootstrap`
* Installs all project dependencies
* Assumes it's running in a virtualenv
* Installs pip, setuptools, and dependencies from requirements.txt (or equivalent)
* Must indirectly call the `install-hooks` target
* Example:
```makefile
bootstrap: install-hooks
pip install --upgrade pip setuptools
pip install -r requirements.txt
```
#### `install-hooks`
* Installs pre-commit hooks and commit-msg hook
* The `hooks/commit-msg` file is managed by github-control
* Example:
```makefile
install-hooks:
pre-commit install
pre-commit install --hook-type commit-msg
```
#### `test`
* Runs the full test suite
* Should run all tests with default configuration
* For Terraform modules: runs tests against all supported AWS provider versions
#### `test-keep`
* Runs tests and keeps infrastructure for debugging
* Useful during local development
* Resources remain after tests complete for troubleshooting
#### `test-clean`
* Runs tests and cleans up all resources
* Must be run before creating PRs to ensure proper cleanup
* Validates that infrastructure can be cleanly destroyed
#### `clean`
* Cleans all build artifacts, temporary files, caches, etc.
* **Do NOT remove Claude Code reviews** (preserve .claude/ directory contents)
* Common cleanups:
- Python: `__pycache__`, `*.pyc`, `.pytest_cache`, `dist/`, `build/`, `*.egg-info`
- Terraform: `.terraform/`, `terraform.tfstate*`, `.terraform.lock.hcl` (in test directories)
* Example:
```makefile
clean:
find . -type d -name __pycache__ -exec rm -rf {} +
find . -type f -name '*.pyc' -delete
rm -rf .pytest_cache dist build *.egg-info
```
#### `format`
* Reformats code to match coding standards
* **For Terraform modules**: Use both `black .` and `terraform fmt -recursive`
* **For Python projects**: Use `black .`
* Should be safe to run repeatedly (idempotent)
* Example:
```makefile
format:
black .
terraform fmt -recursive
```
#### `lint`
* Runs project-specific linters and formatting tools in check mode
* Should NOT modify files, only report issues
* Exit with non-zero status if issues found (for CI/CD)
* **For Python**: Check with `black --check .` and `pylint`
* **For Terraform**: Use `terraform fmt -check -recursive` and `terraform validate`
* Example:
```makefile
lint:
black --check .
pylint my_module
terraform fmt -check -recursive
```
#### `release-*` targets
* Automate the release process
* Run git-cliff for changelog generation
* Run bumpversion to update version numbers
* Common targets:
- `release-patch`: Patch version bump (e.g., 1.2.3 → 1.2.4)
- `release-minor`: Minor version bump (e.g., 1.2.3 → 1.3.0)
- `release-major`: Major version bump (e.g., 1.2.3 → 2.0.0)
* Example:
```makefile
release-patch:
git-cliff --tag $(shell bumpversion --dry-run --list patch | grep new_version | cut -d= -f2) -o CHANGELOG.md
bumpversion patch
git push && git push --tags
```
### Target Naming Conventions
* Use lowercase with hyphens for multi-word targets (e.g., `test-clean`, `install-hooks`)
* Use descriptive names that clearly indicate the action
* Group related targets with common prefixes (e.g., `release-*`, `test-*`)
### PHONY Targets
* Declare all targets that don't produce files as `.PHONY`
* Prevents conflicts with files of the same name
* Improves performance by skipping timestamp checks
* Example:
```makefile
.PHONY: help bootstrap install-hooks test test-keep test-clean clean format lint
```
### Best Practices
* Use `?=` for variables that users can override (e.g., `TEST_REGION ?= us-west-2`)
* Document complex targets with comments
* Keep targets focused - one clear purpose per target
* Chain related targets using dependencies (e.g., `bootstrap: install-hooks`)
* Use consistent indentation (tabs, not spaces, per Make syntax requirements)
EOT -> null
- file = "./.claude/CODING_STANDARD.md" -> null
- id = "terraform-aws-aerospike/./.claude/CODING_STANDARD.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "b179d0bf94ac6d2e023ede4609fa539313d16a9f" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.commit_msg_hook[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "commit_msg_hook" {
- commit_message = "Add commit-msg hook" -> null
- commit_sha = "d7723e724e75acf564ff3575ce3f3a60414830c6" -> null
- content = <<-EOT
#!/usr/bin/env bash
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
# Validates commit messages follow conventional commit format
# See: https://www.conventionalcommits.org/
set -e
commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")
# Skip validation for merge commits
if echo "$commit_msg" | grep -qE '^Merge (branch|pull request)'; then
exit 0
fi
# Conventional commit pattern
# Supports: type(scope): description or type: description
# Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, security
# Optional ! for breaking changes: feat!: description
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|security)(\(.+\))?!?: .{1,}'
if ! echo "$commit_msg" | grep -qE "$pattern"; then
echo "❌ Invalid commit message format"
echo ""
echo "📝 Commit message must follow Conventional Commits:"
echo ""
echo " <type>[optional scope][!]: <description>"
echo ""
echo " [optional body]"
echo ""
echo " [optional footer(s)]"
echo ""
echo "Types:"
echo " feat: ✨ New feature"
echo " fix: 🐛 Bug fix"
echo " docs: 📚 Documentation changes"
echo " security: 🔒 Security improvements"
echo " refactor: ♻️ Code refactoring (no functional changes)"
echo " perf: ⚡ Performance improvement"
echo " test: ✅ Adding or updating tests"
echo " build: 🔧 Build system or dependency changes"
echo " ci: 👷 CI/CD configuration changes"
echo " chore: 🔨 Maintenance tasks"
echo " revert: ⏪ Revert a previous commit"
echo " style: 💄 Code style changes (formatting, etc.)"
echo ""
echo "Breaking changes:"
echo " Use ! after type: feat!: breaking change description"
echo ""
echo "Examples:"
echo " ✓ feat: add deregistration delay configuration"
echo " ✓ fix: correct unhealthy threshold variable name"
echo " ✓ security: add S3 bucket encryption for access logs"
echo " ✓ docs: improve variable descriptions using HEREDOC"
echo " ✓ feat(alb): add listener rule priority documentation"
echo " ✓ feat!: remove deprecated variables (breaking change)"
echo ""
echo "Your message:"
echo " $commit_msg"
echo ""
echo "See: https://www.conventionalcommits.org/"
exit 1
fi
# Success - message is valid
exit 0
EOT -> null
- file = "./hooks/commit-msg" -> null
- id = "terraform-aws-aerospike/./hooks/commit-msg" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "2c6902b370aa03e7b37d11b38c64af3758fdd0af" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.contributing_md[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "contributing_md" {
- commit_message = "Add CONTRIBUTING.md" -> null
- commit_sha = "914df641eedefacfe3d40ab8875084459100d50e" -> null
- content = <<-EOT
# Contributing to this Project
Thank you for your interest in contributing! This document provides guidelines for contributing to this Terraform module.
## How to Contribute
### Reporting Issues
- Check existing issues before creating a new one
- Use a clear, descriptive title
- Include Terraform and provider versions
- Provide minimal reproduction steps
- Include relevant logs or error messages
### Submitting Changes
1. Fork the repository
2. Create a feature branch from `main`
3. Make your changes following our coding standards
4. Write or update tests as needed
5. Run `make test-clean` to verify all tests pass
6. Submit a pull request
### Pull Request Guidelines
- Reference any related issues
- Provide a clear description of changes
- Ensure CI checks pass
- Keep changes focused and atomic
- Update documentation if needed
## Development Setup
```bash
# Clone your fork
git clone https://github.com/YOUR_USERNAME/REPO_NAME.git
cd REPO_NAME
# Install dependencies
make bootstrap
# Run tests (keeps infrastructure for debugging)
make test-keep
# Run tests with cleanup (before PR)
make test-clean
```
## Coding Standards
Please follow the coding standards defined in `.claude/CODING_STANDARD.md`:
- Use `terraform fmt` for formatting
- Follow naming conventions (snake_case)
- Add descriptions to all variables and outputs
- Include validation blocks where appropriate
- Use conventional commits for commit messages
## Commit Message Format
We use [Conventional Commits](https://www.conventionalcommits.org/):
```
feat: Add support for custom IAM policies
fix: Correct security group ingress rules
docs: Update README with new examples
refactor: Simplify variable validation logic
```
## Testing
- Tests use pytest with pytest-infrahouse fixtures
- Tests create real AWS infrastructure
- Always run `make test-clean` before submitting PR
- Ensure tests pass for all supported AWS provider versions
## Questions?
- Open a GitHub issue for questions about contributing
- See [SECURITY.md](SECURITY.md) for reporting security vulnerabilities
## License
By contributing, you agree that your contributions will be licensed under the same license as the project.
EOT -> null
- file = "CONTRIBUTING.md" -> null
- id = "terraform-aws-aerospike/CONTRIBUTING.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "ef7b1b826d1267cd2b91ef7379d29b1211b53403" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.docs_index[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "docs_index" {
- commit_message = "Add docs/index.md" -> null
- commit_sha = "b2242bfe2e17f6306976b096643bed85c53fff3a" -> null
- content = <<-EOT
# terraform-aws-aerospike
Module that deploys Aerospike cluster.
EOT -> null
- file = "./docs/index.md" -> null
- id = "terraform-aws-aerospike/./docs/index.md" -> null
- overwrite_on_create = false -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "925adda8441786c63cf57022fd55c18271bb4fcb" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.docs_workflow[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "docs_workflow" {
- commit_message = "Add docs.yml workflow for GitHub Pages" -> null
- commit_sha = "bfae49da9ca1477f4adf0b3121e93f243ceb969b" -> null
- content = <<-EOT
---
name: 'Deploy Documentation'
on: # yamllint disable-line rule:truthy
push:
branches:
- main
paths:
- 'docs/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
workflow_dispatch: # Allow manual trigger
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
name: 'Build Documentation'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for git info
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.14'
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-mkdocs-${{ hashFiles('**/requirements-docs.txt') }}
restore-keys: |
${{ runner.os }}-pip-mkdocs-
- name: Install dependencies
run: |
make bootstrap
- name: Build documentation
run: mkdocs build --strict
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: site
deploy:
name: 'Deploy to GitHub Pages'
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
EOT -> null
- file = "./.github/workflows/docs.yml" -> null
- id = "terraform-aws-aerospike/./.github/workflows/docs.yml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "516976f8310805db0cfc8e958b080e139e9609ce" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.license[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "license" {
- commit_message = "Add LICENSE" -> null
- commit_sha = "467b46c890e2117d94a2d93617464e3de3c633d9" -> null
- content = <<-EOT
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2024 InfraHouse Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
EOT -> null
- file = "LICENSE" -> null
- id = "terraform-aws-aerospike/LICENSE" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "ea91bcce42a05d55ab51578c0e06fbbd823093d0" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.makefile_example[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "makefile_example" {
- commit_message = "Add Makefile-example" -> null
- commit_sha = "a25909e3dca93bae455e1838b970cce50d127bb3" -> null
- content = <<-EOT
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
.DEFAULT_GOAL := help
define PRINT_HELP_PYSCRIPT
import re, sys
for line in sys.stdin:
match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
if match:
target, help = match.groups()
print("%-40s %s" % (target, help))
endef
export PRINT_HELP_PYSCRIPT
TEST_REGION="us-west-2"
TEST_ROLE="arn:aws:iam::303467602807:role/openvpn-tester"
TEST_SELECTOR="aws6"
help: install-hooks
@python -c "$$PRINT_HELP_PYSCRIPT" < Makefile
.PHONY: install-hooks
install-hooks: ## Install repo hooks
@echo "Checking and installing hooks"
@test -d .git/hooks || (echo "Looks like you are not in a Git repo" ; exit 1)
@test -L .git/hooks/pre-commit || ln -fs ../../hooks/pre-commit .git/hooks/pre-commit
@chmod +x .git/hooks/pre-commit
.PHONY: test
test: ## Run tests on the module
pytest -xvvs tests/
.PHONY: test-keep
test-keep: ## Run a test and keep resources
pytest -xvvs \
--aws-region=${TEST_REGION} \
--test-role-arn=${TEST_ROLE} \
-k $(TEST_SELECTOR) \
--keep-after \
tests/test_module.py 2>&1 | tee pytest-$(shell date +%Y%m%d-%H%M%S)-output.log
.PHONY: test-clean
test-clean: ## Run a test and destroy resources
pytest -xvvs \
--aws-region=${TEST_REGION} \
--test-role-arn=${TEST_ROLE} \
-k $(TEST_SELECTOR) \
tests/test_module.py 2>&1 | tee pytest-$(shell date +%Y%m%d-%H%M%S)-output.log
.PHONY: lint
lint: ## Check code style
yamllint \
.github/workflows
terraform fmt -check -recursive
.PHONY: bootstrap
bootstrap: ## bootstrap the development environment
pip install -U "pip ~= 25.2"
pip install -U "setuptools ~= 80.9"
pip install -r requirements.txt
.PHONY: clean
clean: ## clean the repo from cruft
rm -rf .pytest_cache
find . -name '.terraform' -exec rm -fr {} +
.PHONY: fmt
fmt: format
.PHONY: format
format: ## Use terraform fmt to format all files in the repo
@echo "Formatting terraform files"
terraform fmt -recursive
black tests portal
define BROWSER_PYSCRIPT
import os, webbrowser, sys
from urllib.request import pathname2url
webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
endef
export BROWSER_PYSCRIPT
BROWSER := python -c "$$BROWSER_PYSCRIPT"
.PHONY: docs
docs: ## generate Sphinx HTML documentation, including API docs
$(MAKE) -C docs clean
$(MAKE) -C docs html
$(BROWSER) docs/_build/html/index.html
EOT -> null
- file = "./.claude/Makefile-example" -> null
- id = "terraform-aws-aerospike/./.claude/Makefile-example" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "1c3661217e0b539d35f8f55de1dfa53f6b87c819" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.mkdocs_config[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "mkdocs_config" {
- commit_message = "Add mkdocs.yml configuration" -> null
- commit_sha = "376a5fd32c78020620b59f91e3f7f74bf20edf8f" -> null
- content = <<-EOT
site_name: InfraHouse terraform-aws-aerospike
site_url: https://infrahouse.github.io/terraform-aws-aerospike/
site_description: Terraform module documentation
site_author: InfraHouse
repo_url: https://github.com/infrahouse/terraform-aws-aerospike
repo_name: infrahouse/terraform-aws-aerospike
theme:
name: material
icon:
logo: material/server
palette:
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.instant
- navigation.tracking
- navigation.sections
- navigation.expand
- navigation.top
- content.code.copy
- content.code.annotate
- search.highlight
- search.share
nav:
- Home: index.md
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
- pymdownx.details
- admonition
- tables
- attr_list
- md_in_html
- toc:
permalink: true
plugins:
- search
- minify:
minify_html: true
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/infrahouse
- icon: fontawesome/solid/globe
link: https://infrahouse.com
copyright: Copyright © 2024-2026 InfraHouse
EOT -> null
- file = "./mkdocs.yml" -> null
- id = "terraform-aws-aerospike/./mkdocs.yml" -> null
- overwrite_on_create = false -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "1db6161e79d7c202057d1fb269d8aad536ff8e3a" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.pre_commit_hook[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "pre_commit_hook" {
- commit_message = "Add pre-commit hook" -> null
- commit_sha = "b320ed501bd583065b2bd6ec30c9788648c8feae" -> null
- content = <<-EOT
#!/usr/bin/env bash
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
set -e
echo "🔍 Running pre-commit checks..."
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "❌ Not in a git repository"
exit 1
fi
# Get the root of the git repository
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# 1. Terraform formatting check
echo "📝 Checking Terraform formatting..."
if ! terraform fmt -check -recursive; then
echo "❌ Terraform files need formatting"
echo " Run: terraform fmt -recursive"
exit 1
fi
echo "✅ Terraform formatting OK"
# 2. Update terraform-docs
if command -v terraform-docs &> /dev/null; then
echo "📚 Updating terraform documentation..."
# Run terraform-docs
if terraform-docs . > /dev/null 2>&1; then
# Check if README.md changed
if git diff --quiet README.md; then
echo "✅ Documentation up to date"
else
echo "📝 README.md updated with terraform-docs"
git add README.md
echo "✅ Documentation changes staged"
fi
else
echo "❌ Failed to generate terraform-docs"
exit 1
fi
else
echo "⚠️ terraform-docs not installed"
echo " Install it: https://terraform-docs.io/user-guide/installation/"
echo " Or: brew install terraform-docs"
echo ""
echo "⚠️ Skipping documentation check"
fi
echo ""
echo "✨ All pre-commit checks passed!"
echo "Happy coding!"
EOT -> null
- file = "./hooks/pre-commit" -> null
- id = "terraform-aws-aerospike/./hooks/pre-commit" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "6208e4a5d893b74f6a93eceabb8503efb87a064c" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.release_workflow[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "release_workflow" {
- commit_message = "Add release.yml workflow" -> null
- commit_sha = "b5e0c7bf2f942459ac76b3b4197851973ab3d362" -> null
- content = <<-EOT
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
---
name: Release
on: # yamllint disable-line rule:truthy
push:
tags:
- 'v[0-9]*'
- '[0-9]*'
permissions:
contents: write
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0 # Fetch all history and tags for changelog generation
- name: Generate changelog for this release
id: git-cliff
uses: orhun/git-cliff-action@v4
with:
config: cliff.toml
args: --current --strip header
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.git-cliff.outputs.content }}
make_latest: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EOT -> null
- file = "./.github/workflows/release.yml" -> null
- id = "terraform-aws-aerospike/./.github/workflows/release.yml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "e19ae22c599687c321b9b1681e536f202d2c07b3" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.renovate_json will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "renovate_json" {
- commit_message = "Configure renovate" -> null
- commit_sha = "20609ec5f51ffd0f5b431fe5cc98326667d9019b" -> null
- content = jsonencode(
{
- "$schema" = "https://docs.renovatebot.com/renovate-schema.json"
- extends = [
- "config:recommended",
]
- packageRules = [
- {
- enabled = false
- matchFileNames = [
- ".github/workflows/terraform-CI.yml",
- ".github/workflows/terraform-CD.yml",
- ".github/workflows/vuln-scanner-pr-public.yml",
- ".github/workflows/vuln-scanner-pr-private.yml",
- ".github/workflows/vuln-scanner-pr.yml",
- ".github/workflows/terraform-review.yml",
- ".github/workflows/docs.yml",
- ".github/workflows/release.yml",
]
- matchManagers = [
- "github-actions",
]
},
]
- prConcurrentLimit = 1
- rebaseWhen = "conflicted"
}
) -> null
- file = "renovate.json" -> null
- id = "terraform-aws-aerospike/renovate.json" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "135e2fc044a0e88a04364e764b3f60325967eaf6" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.review_local_command[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "review_local_command" {
- commit_message = "Add review-local Claude command" -> null
- commit_sha = "75fa0ca3182cf7e52a6c121c7c6d702bce21f726" -> null
- content = <<-EOT
---
description: Run Terraform module review locally (similar to GitHub PR review)
---
You are running a local Terraform module review, similar to the automated GitHub PR review workflow.
## Your Task
1. **Create review directory:**
```bash
mkdir -p .claude/reviews
```
2. **Check for previous review:**
- Look for `.claude/reviews/terraform-module-review.md`
- If it exists, this is a follow-up review (read the existing file as the "previous" review)
- If it doesn't exist, this is the first review
3. **Get changes to review:**
- First, check what changes exist:
```bash
# Check for uncommitted changes
git status --short
# Check for commits ahead of main/master
git log --oneline origin/main..HEAD 2>/dev/null || git log --oneline origin/master..HEAD 2>/dev/null || echo "No remote branch found"
```
- Based on what's found, create a diff file in .claude/reviews/:
- **If there are uncommitted changes:** `git diff HEAD > .claude/reviews/pr-changes.diff`
- **If there are committed changes ahead of main:** `git diff origin/main...HEAD > .claude/reviews/pr-changes.diff` (or origin/master)
- **If no changes:** Tell the user there's nothing to review
4. **Show the user what will be reviewed:**
```bash
echo "Changes to review:"
cat .claude/reviews/pr-changes.diff | head -50
echo ""
echo "Total lines in diff: $(wc -l < .claude/reviews/pr-changes.diff)"
```
5. **Launch the terraform-module-reviewer agent:**
**For FIRST review (no previous review found):**
```
Launch the terraform-module-reviewer agent.
Review all changes in .claude/reviews/pr-changes.diff file.
Focus your review on the changes made while considering the overall module context.
Analyze what was added, modified, or removed, and assess the impact on:
- Security
- Functionality
- Best practices compliance
- Code standards
IMPORTANT: Save your complete review to .claude/reviews/terraform-module-review.md
as specified in your agent instructions.
```
**For FOLLOW-UP review (previous review exists):**
```
Launch the terraform-module-reviewer agent.
This is a follow-up review.
Read the previous review from .claude/reviews/terraform-module-review.md
and the current changes in .claude/reviews/pr-changes.diff.
Compare the previous findings with the current state:
- Mark issues as '✅ FIXED:' if they have been resolved
- Mark issues as '⚠️ STILL PRESENT:' if unaddressed
- Mark new issues as '🆕 NEW:' if they appear for the first time
- Provide a summary at the top showing progress
(e.g., '3 issues fixed, 1 still present, 2 new issues found')
Focus on showing what has improved and what still needs attention.
IMPORTANT: Overwrite .claude/reviews/terraform-module-review.md with your
new review (replacing the previous one) as specified in your agent instructions.
```
6. **After the agent completes:**
- Verify the review was created/updated: `ls -lh .claude/reviews/terraform-module-review.md`
- Show the user where to find it
- Let them know they can:
- Read the review now
- Make changes and run /review again to see what improved
## Important Notes
- This review runs **locally** - it won't post to GitHub
- The review helps you catch issues **before** creating a PR
- You can iterate: make changes → run /review again → see what improved
- Each /review run overwrites the previous review (showing your progress)
- When you're satisfied, create your PR and the GitHub workflow will do the official review
EOT -> null
- file = "./.claude/commands/review-local.md" -> null
- id = "terraform-aws-aerospike/./.claude/commands/review-local.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "b74944bfc72a860fe5483bbaafab43679d451ad9" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.security_md[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "security_md" {
- commit_message = "Add SECURITY.md" -> null
- commit_sha = "83ec9473bcb413c233c1c6471c00cbcfec92417e" -> null
- content = <<-EOT
# Security Policy
## Reporting a Vulnerability
We take security seriously. If you discover a security vulnerability in this project, please report it responsibly.
**Please DO NOT create a public GitHub issue for security vulnerabilities.**
### How to Report
Send an email to **security@infrahouse.com** with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested fixes (optional)
### What to Expect
- **Acknowledgment:** Within 48 hours of your report
- **Initial Assessment:** Within 5 business days
- **Resolution Timeline:** Depends on severity, typically 30-90 days
### Scope
This policy applies to:
- The Terraform module code in this repository
- Associated documentation and examples
### Out of Scope
- Issues in upstream dependencies (report to respective maintainers)
- Issues in AWS services (report to AWS)
## Security Best Practices
When using this module:
- Follow the principle of least privilege for IAM roles
- Enable encryption at rest and in transit where applicable
- Review the module's security group and IAM policy configurations
- Keep the module updated to the latest version
## Supported Versions
We provide security updates for the latest major version only.
| Version | Supported |
| ------- | ------------------ |
| Latest | :white_check_mark: |
| Older | :x: |
EOT -> null
- file = "SECURITY.md" -> null
- id = "terraform-aws-aerospike/SECURITY.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "6499f88d7169913b6c20c726577018e13ba29c70" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.terraform_docs_config[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "terraform_docs_config" {
- commit_message = "Add .terraform-docs.yml configuration" -> null
- commit_sha = "4c1e5da141ad5e7426c4372bbfeacc1e9425f8c3" -> null
- content = <<-EOT
---
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
formatter: markdown table
version: ""
recursive:
enabled: false
sections:
hide: []
show: []
content: |-
{{ .Requirements }}
{{ .Providers }}
{{ .Modules }}
{{ .Resources }}
{{ .Inputs }}
{{ .Outputs }}
output:
file: README.md
mode: inject
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->
output-values:
enabled: false
from: ""
sort:
enabled: true
by: name
settings:
anchor: true
color: true
default: true
description: true
escape: true
hide-empty: false
html: true
indent: 2
lockfile: true
read-comments: true
required: true
sensitive: true
type: true
EOT -> null
- file = "./.terraform-docs.yml" -> null
- id = "terraform-aws-aerospike/./.terraform-docs.yml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "b5693869433a1aa8bd44cae6bb558446102ef158" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.terraform_module_reviewer[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "terraform_module_reviewer" {
- commit_message = "Add terraform-module-reviewer Claude agent" -> null
- commit_sha = "8692836437136cc2721393c5635b0ed227160c67" -> null
- content = <<-EOT
<!--
This file is managed by Terraform in github-control repository
Do not edit this file, all changes will be overwritten
If you need to change this file, create a pull request in
https://github.com/infrahouse8/github-control
-->
---
name: terraform-module-reviewer
description: Use this agent when you need to review Terraform module code for adherence to IaC best practices, security standards, and AWS architectural patterns. This agent examines module quality, questions implementation decisions, and ensures alignment with InfraHouse standards and Terraform best practices. Examples:\n\n<example>\nContext: The user has just created a new Terraform module for Lambda functions.\nuser: "I've finished implementing the core Lambda module structure"\nassistant: "I'll review your Lambda module implementation using the terraform-module-reviewer agent"\n<commentary>\nSince new Terraform code was written that needs review for best practices and AWS integration patterns, use the Task tool to launch the terraform-module-reviewer agent.\n</commentary>\n</example>\n\n<example>\nContext: The user has added CloudWatch alarms to a module.\nuser: "I've added error monitoring and SNS integration to the module"\nassistant: "Let me use the terraform-module-reviewer agent to review your monitoring implementation"\n<commentary>\nThe user has completed monitoring features that should be reviewed for CloudWatch best practices and alarm configuration.\n</commentary>\n</example>\n\n<example>\nContext: The user has refactored IAM policies in a module.\nuser: "I've restructured the IAM permissions to follow least privilege principles"\nassistant: "I'll have the terraform-module-reviewer agent examine your IAM refactoring"\n<commentary>\nA security-related refactoring has been done that needs review for IAM best practices and principle of least privilege.\n</commentary>\n</example>
model: sonnet
color: blue
---
You are an expert Terraform/IaC engineer specializing in AWS infrastructure code review and module architecture.
You possess deep knowledge of Terraform best practices, AWS Well-Architected Framework, and infrastructure security.
Your expertise spans the InfraHouse ecosystem, AWS services, Python (for Lambda functions), and Infrastructure as Code patterns.
You have comprehensive understanding of:
- Terraform module design patterns and reusability principles
- AWS service best practices (Lambda, CloudWatch, IAM, SNS, S3, etc.)
- InfraHouse module standards and existing patterns
- Security best practices (least privilege IAM, encryption, secrets management)
- The established coding standards documented in CODING_STANDARD.md amd https://www.terraform-best-practices.com/
- Common Terraform pitfalls and anti-patterns to avoid
- Cost optimization and performance considerations
- State management and module versioning strategies
**Documentation References**:
- Consult https://www.terraform-best-practices.com/ for Terraform coding standards
- Review existing InfraHouse modules for organizational patterns
- Check AWS Well-Architected Framework for infrastructure design principles
When reviewing Terraform modules, you will:
1. **Analyze Module Structure & Quality**:
- Verify proper file organization (variables.tf, main.tf/resources organized by type, outputs.tf, versions.tf)
- Check resource naming conventions (snake_case for resources, descriptive names)
- Ensure all variables have descriptions, types, and validation rules where appropriate
- Validate that default values are sensible and documented
- Confirm proper use of locals for DRY principles
- Check for 2-space indentation and HCL formatting standards
2. **Review Variables & Inputs**:
- Ensure all required variables are properly documented
- Validate that variable types are specific (not just "any")
- Check for appropriate validation rules (regex, contains, conditionals)
- Verify sensible defaults that follow AWS/InfraHouse best practices
- Look for missing variables that would improve reusability
- Ensure sensitive variables are marked as sensitive = true
3. **Assess AWS Resource Configuration**:
- Verify IAM policies follow least privilege principle
- Check that encryption is enabled where applicable (at-rest and in-transit)
- Ensure CloudWatch logging and monitoring are properly configured
- Validate proper resource tagging strategy
- Check for hardcoded values that should be variables
- Verify proper use of data sources vs. resources
- Ensure depends_on is used appropriately to avoid race conditions
- Use aws_iam_policy_document data source instead of crafting a policy from a JSON
4. **Security & Compliance Review**:
- IAM: Check for overly permissive policies (avoid "*" actions/resources)
- Secrets: Ensure no secrets are hardcoded; use AWS Secrets Manager/SSM
- Encryption: Verify KMS keys, S3 bucket encryption, EBS encryption
- Network: Check security group rules, VPC configurations
- Logging: Ensure audit trails and CloudWatch Logs are configured
- Public Access: Verify no unintended public exposure
5. **Evaluate Outputs & Reusability**:
- Check that all important resource attributes are exported
- Ensure output descriptions are clear and helpful
- Verify outputs that other modules might need (ARNs, IDs, names)
- Look for missing outputs that would improve module composition
- Validate that sensitive outputs are marked as sensitive = true
6. **Provider & Version Management**:
- Verify versions.tf has proper Terraform version constraint
- Check AWS provider version constraints (support v5 and v6 for InfraHouse)
- Ensure required_providers block is complete
- Validate that provider features are used correctly
7. **Review Testing Strategy**:
- Check if tests exist for the module
- Verify tests cover multiple AWS provider versions
- Ensure tests validate actual resource creation
- Look for parameterized tests (different configurations)
- Validate proper cleanup in tests
8. **Provide Constructive Feedback**:
- Explain the "why" behind each concern or suggestion
- Reference specific Terraform documentation or existing InfraHouse patterns
- Prioritize issues by severity (critical, important, minor)
- Suggest concrete improvements with HCL code examples when helpful
- Reference AWS Well-Architected Framework principles where relevant
9. **Save Review Output**:
- Save your complete review to: `./.claude/reviews/terraform-module-review.md`
- Include "Last Updated: YYYY-MM-DD" at the top
- Structure the review with clear sections:
- Executive Summary
- Critical Issues (must fix before use)
- Security Concerns
- Important Improvements (should fix)
- Minor Suggestions (nice to have)
- Missing Features
- Testing Recommendations
- Next Steps
10. **Return to Parent Process**:
- Inform the parent Claude instance: "Terraform module review saved to: ./.claude/reviews/terraform-module-review.md"
- Include a brief summary of critical findings and security concerns
- **IMPORTANT**: Explicitly state "Please review the findings and approve which changes to implement before I proceed with any fixes."
- Do NOT implement any fixes automatically
You will be thorough but pragmatic, focusing on issues that truly matter for infrastructure reliability, security, maintainability, and cost optimization. You question every implementation choice with the goal of ensuring the Terraform module is production-ready, secure, and aligns with InfraHouse standards.
Remember: Your role is to be a thoughtful critic who ensures infrastructure code not only deploys successfully but is secure, cost-effective, maintainable, and follows AWS and Terraform best practices. Always save your review and wait for explicit approval before any changes are made.
**Special Considerations for InfraHouse Modules**:
- Modules should be reusable across multiple projects
- Support both AWS provider v5 and v6
- Include comprehensive variable validation
- Export all useful outputs for module composition
- Include examples and proper documentation
- Follow the testing patterns established in other InfraHouse modules
EOT -> null
- file = "./.claude/agents/terraform-module-reviewer.md" -> null
- id = "terraform-aws-aerospike/./.claude/agents/terraform-module-reviewer.md" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "ac25d27ff723b9d8eb65fed5574f49dc774b5746" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.terraform_review_workflow[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "terraform_review_workflow" {
- commit_message = "Add terraform-review.yml workflow" -> null
- commit_sha = "043379d6bcf55c0fa634e60f84f8d20004ac5765" -> null
- content = <<-EOT
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
---
name: Terraform Module Review
on: # yamllint disable-line rule:truthy
pull_request:
paths-ignore:
- '.github/workflows/**'
concurrency:
group: terraform-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for proper diff
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Create reviews directory
run: mkdir -p .claude/reviews .claude/previous-review
- name: Download previous review from PR comment
id: download_previous
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Find existing comment with review
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.body.includes('<!-- terraform-review-bot -->')
);
if (botComment) {
// Extract review content (remove header and marker)
const body = botComment.body;
const reviewStart = body.indexOf('\n\n') + 2; // Skip "## 🤖 Terraform Module Review\n\n"
const reviewEnd = body.lastIndexOf('\n\n<!-- terraform-review-bot -->');
const reviewContent = body.substring(reviewStart, reviewEnd);
// Save to file
fs.writeFileSync('.claude/previous-review/terraform-module-review.md', reviewContent);
console.log('Previous review extracted from PR comment');
return { has_previous: true };
} else {
console.log('No previous review found - this is the first review');
return { has_previous: false };
}
- name: Check for previous review
id: check_previous
run: |
if [ -f ".claude/previous-review/terraform-module-review.md" ]; then
echo "has_previous=true" >> $GITHUB_OUTPUT
echo "Previous review found"
else
echo "has_previous=false" >> $GITHUB_OUTPUT
echo "No previous review found - this is the first review"
fi
- name: Get PR diff
id: diff
run: |
# Get the diff between base and head
git fetch origin ${{ github.event.pull_request.base.ref }}
git diff origin/${{ github.event.pull_request.base.ref }}...HEAD > pr-changes.diff
echo "Changes in this PR:"
cat pr-changes.diff
- name: Run Terraform Module Review (First Review)
if: steps.check_previous.outputs.has_previous == 'false'
run: |
npx @anthropic-ai/claude-code --print --output-format json \
--dangerously-skip-permissions \
"Launch the terraform-module-reviewer agent. \
Review all changes in pr-changes.diff file. \
Focus your review on the changes made in this PR while \
considering the overall module context. \
Analyze what was added, modified, or removed, and assess \
the impact on the module's security, functionality, and \
best practices compliance. \
IMPORTANT: Save your complete review to \
.claude/reviews/terraform-module-review.md as specified in \
your agent instructions." \
> claude-output.json
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Run Terraform Module Review (Follow-up Review)
if: steps.check_previous.outputs.has_previous == 'true'
run: |
npx @anthropic-ai/claude-code --print --output-format json \
--dangerously-skip-permissions \
"Launch the terraform-module-reviewer agent. \
This is a follow-up review. \
Read the previous review from \
.claude/previous-review/terraform-module-review.md and the \
current changes in pr-changes.diff. \
Compare the previous findings with the current state:
- Mark issues as '✅ FIXED:' if they have been resolved
- Mark issues as '⚠️ STILL PRESENT:' if unaddressed
- Mark new issues as '🆕 NEW:' if they appear for the \
first time
- Provide a summary at the top showing progress \
(e.g., '3 issues fixed, 1 still present, 2 new issues found')
Focus on showing what has improved and what still needs \
attention.
IMPORTANT: Save your complete review to \
.claude/reviews/terraform-module-review.md as specified in \
your agent instructions." \
> claude-output.json
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Check if review file exists
id: check_review
run: |
if [ -f ".claude/reviews/terraform-module-review.md" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Review file created successfully"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "Warning: Review file not found"
fi
- name: Upload Claude Output
if: always()
uses: actions/upload-artifact@v4
with:
name: claude-output
path: claude-output.json
- name: Post Review as PR Comment
if: steps.check_review.outputs.exists == 'true' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reviewContent = fs.readFileSync('.claude/reviews/terraform-module-review.md', 'utf8');
// Truncate if too long for GitHub comment (65536 char limit)
const maxLength = 65000;
const content = reviewContent.length > maxLength
? reviewContent.substring(0, maxLength) + '\n\n... (truncated)'
: reviewContent;
const body = `## 🤖 Terraform Module Review\n\n${content}\n\n<!-- terraform-review-bot -->`;
// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.body.includes('<!-- terraform-review-bot -->')
);
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
console.log('Updated existing review comment');
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
console.log('Created new review comment');
}
EOT -> null
- file = "./.github/workflows/terraform-review.yml" -> null
- id = "terraform-aws-aerospike/./.github/workflows/terraform-review.yml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "871128e7bde22a23c02d7e86fbcfacd4b668ee4b" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_file.vuln_scanner_workflow will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_file" "vuln_scanner_workflow" {
- commit_message = "Update vuln-scanner-pr.yml workflow" -> null
- commit_sha = "92cf4ff65aeee91357f4f3acd8d9a3d2b22c4676" -> null
- content = <<-EOT
# This file is managed by Terraform in github-control repository
# Do not edit this file, all changes will be overwritten
# If you need to change this file, create a pull request in
# https://github.com/infrahouse8/github-control
---
name: OSV-Scanner PR Scan
on: # yamllint disable-line rule:truthy
pull_request:
branches: [main]
permissions:
# Required to upload SARIF file to CodeQL. See: https://github.com/github/codeql-action/issues/2117
actions: read
# Require writing security events to upload SARIF file to security tab
security-events: write
# Only need to read contents
contents: read
jobs:
vulnerability-check:
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v2.3.0"
with:
scan-args: --config osv-scanner.toml
upload-sarif: false
EOT -> null
- file = "./.github/workflows/vuln-scanner-pr.yml" -> null
- id = "terraform-aws-aerospike/./.github/workflows/vuln-scanner-pr.yml" -> null
- overwrite_on_create = true -> null
- ref = "main" -> null
- repository = "terraform-aws-aerospike" -> null
- sha = "f0ac21e82bda03955630463b842905ab3f111173" -> null
}
# module.repos["terraform-aws-aerospike"].github_repository_ruleset.main[0] will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_repository_ruleset" "main" {
- enforcement = "active" -> null
- etag = "W/\"55878fd8b72e3bfddc6837080d82ed290b3b633c5ed400c3553f289189e24ff5\"" -> null
- id = "8194318" -> null
- name = "Main Branch Protection" -> null
- node_id = "RRS_lACqUmVwb3NpdG9yec4uEEVzzgB9CQ4" -> null
- repository = "terraform-aws-aerospike" -> null
- ruleset_id = 8194318 -> null
- target = "branch" -> null
- bypass_actors {
- actor_id = 1016363 -> null
- actor_type = "Integration" -> null
- bypass_mode = "always" -> null
}
- bypass_actors {
- actor_id = 14268696 -> null
- actor_type = "Team" -> null
- bypass_mode = "always" -> null
}
- conditions {
- ref_name {
- exclude = [] -> null
- include = [
- "~DEFAULT_BRANCH",
] -> null
}
}
- rules {
- creation = false -> null
- deletion = false -> null
- non_fast_forward = false -> null
- required_linear_history = false -> null
- required_signatures = false -> null
- update = false -> null
- update_allows_fetch_and_merge = false -> null
- pull_request {
- dismiss_stale_reviews_on_push = true -> null
- require_code_owner_review = true -> null
- require_last_push_approval = false -> null
- required_approving_review_count = 1 -> null
- required_review_thread_resolution = false -> null
}
- required_status_checks {
- do_not_enforce_on_create = false -> null
- strict_required_status_checks_policy = true -> null
- required_check {
- context = "vulnerability-check / osv-scan" -> null
- integration_id = 0 -> null
}
}
}
}
# module.repos["terraform-aws-aerospike"].github_team_repository.admin will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_team_repository" "admin" {
- etag = "W/\"f54ae922cbae6401b2c52d6f4a1e275c95cab8db3ecd585780f64655d71f8c7c\"" -> null
- id = "14268696:terraform-aws-aerospike" -> null
- permission = "admin" -> null
- repository = "terraform-aws-aerospike" -> null
- team_id = "14268696" -> null
}
# module.repos["terraform-aws-aerospike"].github_team_repository.dev will be destroyed
# (because module.repos["terraform-aws-aerospike"] is not in configuration)
- resource "github_team_repository" "dev" {
- etag = "W/\"cda9e0cde5e89a7de574dcf2d348e827c9839110c6dad071fa0e5e1e85c01656\"" -> null
- id = "7332815:terraform-aws-aerospike" -> null
- permission = "push" -> null
- repository = "terraform-aws-aerospike" -> null
- team_id = "7332815" -> null
}
# module.repos["terraform-aws-bookstack"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that deploys BookStack." -> "Terraform module for BookStack wiki and documentation platform on AWS with RDS database, S3 storage, ALB with SSL, and OIDC authentication. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-bookstack"
id = "terraform-aws-bookstack"
name = "terraform-aws-bookstack"
~ topics = [
+ "aws",
+ "bookstack",
+ "documentation",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
+ "wiki",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-ci-cd"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates roles, state bucket, and dynamodb table for Terraform CI/CD." -> "Terraform module that creates IAM roles, S3 state bucket, and DynamoDB lock table for Terraform CI/CD pipelines with GitHub Actions integration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-ci-cd"
id = "terraform-aws-ci-cd"
name = "terraform-aws-ci-cd"
~ topics = [
+ "aws",
+ "ci-cd",
+ "github-actions",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-cloud-init"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a cloud init configuration for an InfraHouse EC2 instance." -> "Terraform module for cloud-init configuration with Puppet integration, custom package installation, file provisioning, and APT repository setup. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-cloud-init"
id = "terraform-aws-cloud-init"
name = "terraform-aws-cloud-init"
~ topics = [
+ "aws",
+ "cloud-init",
+ "ec2",
+ "infrahouse",
+ "puppet",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-cloudcraft-role"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a role for CloudCraft scanner." -> "Terraform module that creates an IAM role for CloudCraft AWS infrastructure visualization and diagramming scanner. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-cloudcraft-role"
id = "terraform-aws-cloudcraft-role"
name = "terraform-aws-cloudcraft-role"
~ topics = [
+ "aws",
+ "cloudcraft",
+ "iam",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
+ "visualization",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-cost-alert"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a alert for AWS cost per period." -> "Terraform module for AWS Budget alerts with SNS email notifications for cost monitoring and threshold-based alerting. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-cost-alert"
id = "terraform-aws-cost-alert"
name = "terraform-aws-cost-alert"
~ topics = [
+ "aws",
+ "budgets",
+ "cost-management",
+ "infrahouse",
+ "monitoring",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-debian-repo"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a Debian repository backed by S3 and fronted by CloudFront." -> "Terraform module for private Debian/APT repository backed by S3 with CloudFront CDN, GPG package signing, and Lambda-based repository indexing. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-debian-repo"
id = "terraform-aws-debian-repo"
name = "terraform-aws-debian-repo"
~ topics = [
+ "apt",
+ "aws",
+ "debian",
+ "infrahouse",
+ "package-repository",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-dms"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module for deploying AWS Data Migration Service" -> "Terraform module for AWS Database Migration Service with replication instances, endpoints, and tasks for database migration and CDC. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-dms"
id = "terraform-aws-dms"
name = "terraform-aws-dms"
~ topics = [
+ "aws",
+ "database",
+ "dms",
+ "infrahouse",
+ "migration",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-ecr"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a container registry (AWS ECR service)." -> "Terraform module for AWS ECR container registry with lifecycle policies, image scanning, encryption, and cross-account repository access. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-ecr"
id = "terraform-aws-ecr"
name = "terraform-aws-ecr"
~ topics = [
+ "aws",
+ "containers",
+ "docker",
+ "ecr",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-ecs"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that runs service in ECS" -> "Terraform module for ECS on EC2 service deployment with ALB integration, auto-scaling, CloudWatch monitoring, secrets injection, and optional Datadog APM. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-ecs"
id = "terraform-aws-ecs"
name = "terraform-aws-ecs"
~ topics = [
+ "aws",
+ "containers",
+ "docker",
+ "ecs",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-elasticsearch"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that deploys an Elasticsearch cluster" -> "Terraform module for self-managed Elasticsearch cluster on EC2 with auto-scaling, S3 snapshots, NLB load balancing, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-elasticsearch"
id = "terraform-aws-elasticsearch"
name = "terraform-aws-elasticsearch"
~ topics = [
+ "aws",
+ "elasticsearch",
+ "infrahouse",
+ "logging",
+ "search",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-emrserverless"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module for deploying EMR serverless" -> "Terraform module for AWS EMR Serverless applications running Apache Spark and Hive workloads with S3 integration and IAM role configuration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-emrserverless"
id = "terraform-aws-emrserverless"
name = "terraform-aws-emrserverless"
~ topics = [
+ "aws",
+ "big-data",
+ "emr",
+ "hive",
+ "infrahouse",
+ "spark",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-gh-identity-provider"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that configures GitHub OpenID connector." -> "Terraform module that configures GitHub OIDC identity provider in AWS IAM for secure, keyless authentication from GitHub Actions workflows. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-gh-identity-provider"
id = "terraform-aws-gh-identity-provider"
name = "terraform-aws-gh-identity-provider"
~ topics = [
+ "aws",
+ "github",
+ "iam",
+ "infrahouse",
+ "oidc",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-gha-admin"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module for two roles to manage AWS with GitHub actions." -> "Terraform module creating admin and read-only IAM roles for GitHub Actions with OIDC trust, branch-based access control, and state management permissions. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-gha-admin"
id = "terraform-aws-gha-admin"
name = "terraform-aws-gha-admin"
~ topics = [
+ "aws",
+ "github",
+ "github-actions",
+ "iam",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-github-backup"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module to provision infrahouse-github-backup GitHub App." -> "Terraform module for Lambda-based GitHub organization backup to S3 with scheduled execution, repository cloning, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-github-backup"
id = "terraform-aws-github-backup"
name = "terraform-aws-github-backup"
~ topics = [
+ "aws",
+ "backup",
+ "github",
+ "infrahouse",
+ "lambda",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-github-backup-configuration"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that configures infrahouse-github-backup GitHub App client." -> "Terraform module for configuring infrahouse-github-backup GitHub App client with secrets, permissions, and backup target configuration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-github-backup-configuration"
id = "terraform-aws-github-backup-configuration"
name = "terraform-aws-github-backup-configuration"
~ topics = [
+ "aws",
+ "backup",
+ "github",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-github-role"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a role for a GitHub Action worker." -> "Terraform module that creates an IAM role with OIDC trust policy for GitHub Actions workflows with customizable permissions and repo/branch restrictions. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-github-role"
id = "terraform-aws-github-role"
name = "terraform-aws-github-role"
~ topics = [
+ "aws",
+ "github",
+ "github-actions",
+ "iam",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-guardduty-configuration"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that configures GuardDuty and email notifications." -> "Terraform module for AWS GuardDuty threat detection with SNS email alerts, S3 finding exports, and configurable severity filtering. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-guardduty-configuration"
id = "terraform-aws-guardduty-configuration"
name = "terraform-aws-guardduty-configuration"
~ topics = [
+ "aws",
+ "guardduty",
+ "infrahouse",
+ "monitoring",
+ "security",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-http-redirect"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module creates an HTTP redirect server." -> "Terraform module for HTTP to HTTPS redirect using CloudFront with custom domain support and SSL certificate management. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-http-redirect"
id = "terraform-aws-http-redirect"
name = "terraform-aws-http-redirect"
~ topics = [
+ "aws",
+ "cloudfront",
+ "infrahouse",
+ "redirect",
+ "ssl",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-instance-profile"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module bundles AWS resources to create an instance profile." -> "Terraform module for EC2 instance profiles with IAM role, managed policies, inline permissions, and optional CloudWatch/SSM integration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-instance-profile"
id = "terraform-aws-instance-profile"
name = "terraform-aws-instance-profile"
~ topics = [
+ "aws",
+ "ec2",
+ "iam",
+ "infrahouse",
+ "instance-profile",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-iso27001"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module configures ISO 27001 compliance for AWS." -> "Terraform module for ISO 27001 compliance including CloudTrail, AWS Config, Security Hub, IAM password policies, and security baseline controls. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-iso27001"
id = "terraform-aws-iso27001"
name = "terraform-aws-iso27001"
~ topics = [
+ "aws",
+ "compliance",
+ "infrahouse",
+ "iso27001",
+ "security",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-jumphost"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a jumphost." -> "Terraform module for bastion/jumphost EC2 instance with SSH access, Route53 DNS registration, security groups, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-jumphost"
id = "terraform-aws-jumphost"
name = "terraform-aws-jumphost"
~ topics = [
+ "aws",
+ "bastion",
+ "ec2",
+ "infrahouse",
+ "ssh",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-key"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates an encryption key in KMS." -> "Terraform module for AWS KMS encryption keys with configurable key policies, key rotation, aliases, and cross-account access grants. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-key"
id = "terraform-aws-key"
name = "terraform-aws-key"
~ topics = [
+ "aws",
+ "encryption",
+ "infrahouse",
+ "kms",
+ "security",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-kibana"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that deploys Kibana" -> "Terraform module for Kibana deployment on ECS with ALB, SSL certificates, and Elasticsearch backend integration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-kibana"
id = "terraform-aws-kibana"
name = "terraform-aws-kibana"
~ topics = [
+ "aws",
+ "ecs",
+ "elasticsearch",
+ "infrahouse",
+ "kibana",
+ "logging",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-lambda-monitored"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
+ homepage_url = "https://infrahouse.github.io/terraform-aws-lambda-monitored"
id = "terraform-aws-lambda-monitored"
name = "terraform-aws-lambda-monitored"
~ topics = [
+ "aws",
+ "infrahouse",
+ "lambda",
+ "monitoring",
+ "serverless",
+ "terraform",
+ "terraform-module",
]
# (33 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-openvpn"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module that deploys OpenVPN server." -> "Terraform module for OpenVPN Access Server on EC2 with Google OAuth/SAML authentication, Let's Encrypt SSL, auto-scaling, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-openvpn"
id = "terraform-aws-openvpn"
name = "terraform-aws-openvpn"
~ topics = [
+ "aws",
+ "infrahouse",
+ "openvpn",
+ "security",
+ "terraform",
+ "terraform-module",
+ "vpn",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-percona-server"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
+ homepage_url = "https://infrahouse.github.io/terraform-aws-percona-server"
id = "terraform-aws-percona-server"
name = "terraform-aws-percona-server"
~ topics = [
+ "aws",
+ "database",
+ "infrahouse",
+ "mysql",
+ "percona",
+ "replication",
+ "terraform",
+ "terraform-module",
]
# (33 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-pmm-ecs"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
+ homepage_url = "https://infrahouse.github.io/terraform-aws-pmm-ecs"
id = "terraform-aws-pmm-ecs"
name = "terraform-aws-pmm-ecs"
~ topics = [
+ "aws",
+ "infrahouse",
+ "monitoring",
+ "mysql",
+ "percona",
+ "pmm",
+ "postgres",
+ "terraform",
+ "terraform-module",
]
# (33 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-postfix"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module that deploys Postfix as a MX server." -> "Terraform module for Postfix MX mail server on EC2 with SpamAssassin, DKIM signing, SPF, DMARC, TLS encryption, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-postfix"
id = "terraform-aws-postfix"
name = "terraform-aws-postfix"
~ topics = [
+ "aws",
+ "email",
+ "infrahouse",
+ "mail-server",
+ "postfix",
+ "smtp",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-pypiserver"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module that deploys a private PyPI server." -> "Terraform module for private PyPI server on EC2 with S3 package storage, ALB with SSL, htpasswd authentication, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-pypiserver"
id = "terraform-aws-pypiserver"
name = "terraform-aws-pypiserver"
~ topics = [
+ "aws",
+ "infrahouse",
+ "package-registry",
+ "pypi",
+ "python",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-registry"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module that deploys a private Terraform registry." -> "Terraform module for private Terraform registry on EC2 with S3 backend, GitHub releases integration, ALB with SSL, and module discovery API. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-registry"
id = "terraform-aws-registry"
name = "terraform-aws-registry"
~ topics = [
+ "aws",
+ "infrahouse",
+ "registry",
+ "terraform",
+ "terraform-module",
+ "terraform-registry",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-s3-bucket"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module for an ISO27001 compliant S3 bucket." -> "Terraform module for ISO 27001 compliant S3 bucket with server-side encryption, versioning, access logging, and public access blocking. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-s3-bucket"
id = "terraform-aws-s3-bucket"
name = "terraform-aws-s3-bucket"
~ topics = [
+ "aws",
+ "infrahouse",
+ "iso27001",
+ "s3",
+ "storage",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-secret"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module for a secret with owner/writer/reader roles." -> "Terraform module for AWS Secrets Manager secrets with owner/writer/reader IAM roles, automatic rotation support, and cross-account access policies. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-secret"
id = "terraform-aws-secret"
name = "terraform-aws-secret"
~ topics = [
+ "aws",
+ "infrahouse",
+ "secrets-manager",
+ "security",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-secret-policy"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module that creates AWS secret permissions policy." -> "Terraform module that creates IAM policies for AWS Secrets Manager access with read, write, and admin permission levels. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-secret-policy"
id = "terraform-aws-secret-policy"
name = "terraform-aws-secret-policy"
~ topics = [
+ "aws",
+ "iam",
+ "infrahouse",
+ "secrets-manager",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-service-network"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform service network module." -> "Terraform module for VPC with public/private subnets across AZs, NAT gateways, internet gateway, route tables, and VPC flow logs. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-service-network"
id = "terraform-aws-service-network"
name = "terraform-aws-service-network"
~ topics = [
+ "aws",
+ "infrahouse",
+ "networking",
+ "subnets",
+ "terraform",
+ "terraform-module",
+ "vpc",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-sqs-ecs"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module deploys an SQS queue with ECS service as a consumer." -> "Terraform module for SQS queue with ECS on EC2 service consumer, CloudWatch-based scaling, dead-letter queue, and container configuration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-sqs-ecs"
id = "terraform-aws-sqs-ecs"
name = "terraform-aws-sqs-ecs"
~ topics = [
+ "aws",
+ "ecs",
+ "infrahouse",
+ "queue",
+ "sqs",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-sqs-pod"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Terraform module deploys an SQS queue with autoscaling group as a consumer." -> "Terraform module for SQS queue with EC2 autoscaling group consumer, CloudWatch-based scaling policies, dead-letter queue, and monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-sqs-pod"
id = "terraform-aws-sqs-pod"
name = "terraform-aws-sqs-pod"
~ topics = [
+ "autoscaling",
+ "aws",
+ "infrahouse",
+ "queue",
+ "sqs",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-state-bucket"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates an S3 bucket for a Terraform state." -> "Terraform module for S3 state bucket with DynamoDB locking table, server-side encryption, versioning, and access logging. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-state-bucket"
id = "terraform-aws-state-bucket"
name = "terraform-aws-state-bucket"
~ topics = [
+ "aws",
+ "dynamodb",
+ "infrahouse",
+ "s3",
+ "terraform",
+ "terraform-module",
+ "terraform-state",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-state-manager"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module creates an IAM role that can manage a Terraform state." -> "Terraform module that creates an IAM role for Terraform state management with S3 bucket and DynamoDB lock table permissions. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-state-manager"
id = "terraform-aws-state-manager"
name = "terraform-aws-state-manager"
~ topics = [
+ "aws",
+ "iam",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
+ "terraform-state",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-tags-override"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module to override tags list for ECS" -> "Terraform module to override values in a list of name/value maps, useful for merging and overriding tag configurations. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-tags-override"
id = "terraform-aws-tags-override"
name = "terraform-aws-tags-override"
~ topics = [
+ "aws",
+ "infrahouse",
+ "tags",
+ "terraform",
+ "terraform-module",
+ "utility",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-tcp-pod"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates an autoscaling group with an NLB for a TCP based services." -> "Terraform module for NLB-fronted EC2 autoscaling group serving TCP services with health checks, target tracking scaling, and DNS registration. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-tcp-pod"
id = "terraform-aws-tcp-pod"
name = "terraform-aws-tcp-pod"
~ topics = [
+ "autoscaling",
+ "aws",
+ "infrahouse",
+ "nlb",
+ "tcp",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-teleport"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module deploys a single node Teleport cluster." -> "Terraform module for single-node Teleport cluster providing secure SSH, Kubernetes, database, and application access with audit logging. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-teleport"
id = "terraform-aws-teleport"
name = "terraform-aws-teleport"
~ topics = [
+ "access-management",
+ "aws",
+ "infrahouse",
+ "security",
+ "teleport",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-teleport-agent"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module deploys roles and other resources on an account joining Teleport cluster." -> "Terraform module for Teleport agent deployment with IAM roles and resources enabling AWS accounts to join an existing Teleport cluster. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-teleport-agent"
id = "terraform-aws-teleport-agent"
name = "terraform-aws-teleport-agent"
~ topics = [
+ "aws",
+ "iam",
+ "infrahouse",
+ "teleport",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-terraformer"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that deploys an instances allowed to manage Terraform root modules." -> "Terraform module for administrative EC2 instance with cross-account AssumeRole capabilities for Terraform operations, DNS registration, and CloudWatch monitoring. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-terraformer"
id = "terraform-aws-terraformer"
name = "terraform-aws-terraformer"
~ topics = [
+ "administration",
+ "aws",
+ "ec2",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-truststore"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates a trust store with a generated CA certificate." -> "Terraform module for ALB Trust Store with auto-generated root CA certificate, private key storage in Secrets Manager, and S3-backed certificate distribution. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-truststore"
id = "terraform-aws-truststore"
name = "terraform-aws-truststore"
~ topics = [
+ "alb",
+ "aws",
+ "certificates",
+ "infrahouse",
+ "ssl",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-update-dns"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module creates a lambda that manages DNS A records for instances in an autoscaling group." -> "Terraform module for Lambda-based Route53 DNS record management that automatically creates/removes A records for autoscaling group instances. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-update-dns"
id = "terraform-aws-update-dns"
name = "terraform-aws-update-dns"
~ topics = [
+ "aws",
+ "dns",
+ "infrahouse",
+ "lambda",
+ "route53",
+ "terraform",
+ "terraform-module",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
# module.repos["terraform-aws-website-pod"].github_repository.repo will be updated in-place
~ resource "github_repository" "repo" {
~ description = "Module that creates an autoscaling group with an ALB and SSL certificate for a website." -> "Terraform module for web application deployment with ALB, ACM SSL certificates, EC2 autoscaling, CloudWatch alarms, CAA records, and spot instance support. "
+ homepage_url = "https://infrahouse.github.io/terraform-aws-website-pod"
id = "terraform-aws-website-pod"
name = "terraform-aws-website-pod"
~ topics = [
+ "alb",
+ "autoscaling",
+ "aws",
+ "infrahouse",
+ "terraform",
+ "terraform-module",
+ "website",
]
# (32 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
Plan: 0 to add, 65 to change, 26 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: tf.plan
To perform exactly these actions, run the following command to apply:
terraform apply "tf.plan"
metadata
eyJzMzovL2luZnJhaG91c2UtZ2l0aHViLWNvbnRyb2wtc3RhdGUvdGVycmFmb3JtLnRmc3RhdGUiOiB7InN1Y2Nlc3MiOiB0cnVlLCAiYWRkIjogMCwgImNoYW5nZSI6IDY1LCAiZGVzdHJveSI6IDI2fX0=
Collaborator
Author
|
Ah, about "terraform-aws-aerospike". This module was unsuccessful experiment and I'm deleting because it didn't make to production use and as of now, I have no plans to explore this further. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
discoverability
HEREDOC
descriptions based on actual README content
python, etc.)
repositories