Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:- iac-recert-engine/internal/engine/engine.go
- iac-recert-engine/cmd/ice/run.go
- iac-recert-engine/internal/config/types.go
- iac-recert-engine/example.config.yaml
- iac-recert-engine/internal/types/types.go
- iac-recert-engine/internal/scan/file_scanner.go
- iac-recert-engine/internal/scan/git_history.go
- iac-recert-engine/internal/scan/recert_checker.go
- iac-recert-engine/internal/strategy/strategy_test.go
- iac-recert-engine/internal/assign/resolver.go
- iac-recert-engine/internal/pr/generator.go
- iac-recert-engine/internal/provider/github.go
- iac-recert-engine/internal/provider/azure.go
The Infrastructure as Code Recertification Engine (ICE) is a command-line tool designed to automate the recertification process for IaC files. It operates by scanning a configured Git repository, identifying files that have not been modified within a specified period, and then automatically creating pull requests to prompt for review and recertification.
The entire process is driven by a central YAML configuration file, allowing for flexible and detailed control over scanning, grouping, and assignment logic. The system is designed to be extensible, primarily through a GitProvider interface that abstracts interactions with different Git hosting services like GitHub, Azure DevOps, and GitLab.
Core Components
The engine is composed of several distinct components, each with a specific responsibility. These components are instantiated and orchestrated by the main Engine struct.
Sources: internal/engine/engine.go:23-74
This diagram illustrates the main components and their relationships within the engine.
The table below describes the role of each major component.
| Component | Description | Source File |
|---|---|---|
| Engine | The central orchestrator that manages the entire recertification workflow from scanning to PR creation. | internal/engine/engine.go |
| GitProvider | An interface for interacting with Git services (e.g., GitHub, Azure). Handles operations like creating branches, commits, and PRs. | internal/provider/github.go |
| Scanner | Clones the target repository and scans the filesystem for files matching the configured patterns. | internal/scan/file_scanner.go |
| HistoryAnalyzer | Enriches file information by fetching Git history, such as the last modification date and author, using the GitProvider. | internal/scan/git_history.go |
| Checker | Compares each file's last modification date against the configured recertification threshold to determine if it needs review. | internal/scan/recert_checker.go |
| Strategy | Groups files that need recertification into logical sets for creating pull requests (e.g., one PR per file, one PR per pattern). | internal/strategy/strategy_test.go |
| Resolver | Determines the assignees and reviewers for a pull request based on the configured assignment strategy (e.g., static list, last committer). | internal/assign/resolver.go |
| PRGenerator | Generates the title and description for a pull request based on a configurable template and the files in the group. | internal/pr/generator.go |
Sources: internal/engine/engine.go:23-34, internal/scan/file_scanner.go:16-22, internal/scan/git_history.go:11-17, internal/scan/recert_checker.go:11-15, internal/assign/resolver.go:12-18, internal/pr/generator.go:10-14, internal/provider/github.go:20-25
Execution Flow
The Engine.Run method orchestrates the recertification process in a series of sequential steps. The process begins with file discovery and ends with the creation of pull requests for files requiring recertification.
Sources: internal/engine/engine.go:77-133
The following flowchart shows the main stages of the Engine.Run method.
- Scan: The
Scannerclones the repository into a temporary directory and finds all files that match the include/exclude glob patterns defined in the configuration.
Sources: internal/scan/file_scanner.go:24-111 - Enrich: The
HistoryAnalyzertakes the list of found files and uses theGitProviderto fetch the last modification date, commit hash, and author for each file.
Sources: internal/scan/git_history.go:20-53 - Check: The
Checkeriterates through the enriched files and determines which ones need recertification by comparing the days since the last modification with therecertification_daysthreshold from the matching pattern. It also assigns a priority (Low,Medium,High,Critical).
Sources: internal/scan/recert_checker.go:17-101 - Group: The
Strategycomponent groups the files marked for recertification. The grouping logic is defined bypr_strategy.typein the config (e.g.,per_pattern,per_committer).
Sources: internal/engine/engine.go:110-114, internal/strategy/strategy_test.go - Process Groups: For each group, the engine performs the final steps:
- Resolve Assignment: The
Resolverdetermines the appropriate assignees for the PR. - Generate PR: The
PRGeneratorcreates the PR title and body. - Create PR: If not in
dry_runmode, theGitProvideris used to create a new branch, commit the file changes (with an updated decorator), and open a pull request.
Sources: internal/engine/engine.go:118-251
- Resolve Assignment: The
Configuration Model
The engine's behavior is entirely controlled by a YAML configuration file, typically named config.yaml. The structure of this file is defined by Go structs in the internal/config package.
Sources: internal/config/types.go, example.config.yaml
Key Configuration Sections
| Section | Description |
|---|---|
repository | Specifies the URL and provider (github, azure, gitlab) of the repository to scan. |
auth | Defines the authentication method, typically an environment variable containing a personal access token. |
global | Global settings like dry_run mode, verbose_logging, and the default_base_branch for PRs. |
patterns | An array of rules for file matching. Each pattern defines glob paths, a recertification_days threshold, and an optional decorator to add to files upon recertification. |
pr_strategy | Defines how to group files into pull requests. Options include per_file, per_pattern, per_committer, and single_pr. |
assignment | Defines how to assign pull requests to users. Options include static, last_committer, and composite. |
pr_template | Configures the template for PR titles and bodies, with support for placeholders like {pattern_name}. |
Sources: example.config.yaml, internal/config/types.go:8-71
Example patterns Configuration
patterns:
- name: "terraform-prod"
description: "Production Terraform configurations"
paths:
- "terraform/prod/**/*.tf"
- "!terraform/prod/modules/**" # Exclude modules
exclude:
- "**/*.test.tf"
recertification_days: 180
enabled: true
decorator: "# Last Recertification: {timestamp}\n"
Sources: example.config.yaml:26-37
Key Data Structures
Data is passed between components using a set of core data structures defined in internal/types/types.go.
This diagram shows the primary data models and their relationships.
Sources: internal/types/types.go
The data flows through the system as follows: FileInfo -> RecertCheckResult -> FileGroup -> PRConfig.
Git Provider Abstraction
To support multiple Git hosting platforms, the engine uses a GitProvider interface. This allows the core logic to remain platform-agnostic while specific implementations handle the API details for services like GitHub, Azure DevOps, and GitLab.
Sources: internal/provider/github.go, internal/provider/azure.go, internal/provider/gitlab.go
PR Creation Sequence
The following sequence diagram shows the interaction between the Engine and a GitProvider implementation when creating a pull request.