import time import re from typing import Dict from .base import BasePRWaiter, BasePromptBuilder, BasePRAnalyzer class AtlantisPRWaiter(BasePRWaiter): """Waits for Atlantis Terraform plan comments before analysis.""" def wait_for_analysis_ready( self, github_client, pr_number: int, timeout: int = 600, interval: int = 10 ) -> Dict: """Wait for Atlantis plan comments to appear after the last commit.""" start_time = time.time() while time.time() - start_time < timeout: pr_status = github_client.get_pr_status(pr_number) atlantis_plan_status = next( ( status for status in pr_status.get('statuses', []) if status['context'] == 'atlantis/plan' ), None, ) if atlantis_plan_status: if atlantis_plan_status['state'] == 'pending': print( f'Atlantis plan is still pending, waiting {interval} seconds...' ) time.sleep(interval) continue else: print( f'Atlantis plan has completed with state: {atlantis_plan_status["state"]}' ) pr_data = github_client.get_pr_details(pr_number) return pr_data else: print( f'No Atlantis plan status check found, waiting {interval} seconds...' ) time.sleep(interval) raise TimeoutError('Timed out waiting for Atlantis plan status check') class TerraformInfraPromptBuilder(BasePromptBuilder): """Terraform Infrastructure specific prompt builder.""" def __init__(self): self.base_prompt = self._get_terraform_prompt_template() def _get_terraform_prompt_template(self) -> str: """Get the comprehensive Terraform PR review prompt template.""" return """# Terraform Pull Request Review Prompt You are an AI assistant tasked with reviewing a Terraform pull request. You will be given the PR title, description, code diff, Terraform plan, and possibly additional context (such as full project files, module versions, inputs). Perform a thorough review, focusing on the following key areas: 1. **Prevention of Infrastructure Outages** – Ensure the changes will not cause downtime or data loss. Look for risky operations in the diff/plan (e.g. resource deletions or replacements of critical resources). Verify use of Terraform features like `moved` blocks or `lifecycle` rules to avoid unintended destroys when renaming or modifying resources. Check that changes are rolled out safely (for example, splitting large changes, not mixing production and non-production updates in one PR). Confirm that any scaling or redundancy best practices are followed (e.g. for web services, running at least two instances across AZs for high availability). 2. **Infrastructure Correctness & Dependency Logic** – Validate that the infrastructure configuration is correct and all dependencies are handled. Ensure resources refer to each other properly (e.g. outputs and module references are wired correctly, no missing `depends_on` where needed). Watch for configuration mistakes that could break functionality (such as incorrect resource names, missing required attributes, or misordered resource creation). If the PR includes Terraform Plan output, make sure the planned changes align with the intentions described. Flag anything that looks like a misconfiguration or would fail at apply time. Also, check that the code adheres to the expected file structure and organization for Terraform projects (e.g. using `main.tf`, `variables.tf`, etc. appropriately, and logical grouping of resources/modules). 3. **Security Best Practices** – Identify any security concerns. Ensure IAM policies follow the principle of least privilege (avoid wildcards like `"*"` in resources or actions unless absolutely necessary and justified). Check that no sensitive secrets or credentials are exposed in the code (plaintext passwords, keys, or tokens should not appear in the diff). Verify that resources are not unintentionally exposed publicly: for AWS security groups and firewall rules, there should be no wide-open CIDR like `0.0.0.0/0` unless explicitly justified (and if so, it's a serious concern to highlight). Ensure secure configurations are in place (for example, S3 buckets should have proper access controls and encryption, load balancers should not have an open HTTP listener without SSL, databases should not be publicly accessible, etc.). The code should use secure protocols and encryption wherever applicable (e.g. enforcing TLS, using KMS for data encryption). If the PR involves specific domains like Snowflake or other services, ensure that it follows the company's security and access management guidelines for those (e.g. proper Snowflake role hierarchy and permissions). Any potential vulnerability or deviation from security policy should be flagged as a blocking issue. 4. **Maintainability & Best Practices** – Assess the readability and maintainability of the code. Check that the changes use existing approved Terraform modules where possible instead of duplicating resource definitions (the organization provides internal modules for common tasks; prefer those for consistency and supportability). All module versions should be pinned (using semver tags) and updated to recommended versions if needed – note if any module version changes in this PR and whether they are major (which might require careful review of breaking changes). Verify that naming conventions are followed (e.g. IAM roles/policies and resource names include environment and service identifiers as per guidelines). Look for any usage of deprecated Terraform resources or attributes and suggest modern alternatives if available (especially given the **2025 Terraform updates** – for instance, if something can be done with a newer feature or module, point it out). Ensure the code is well-structured (avoiding overly large files or deeply nested logic that hurts clarity) and variables/outputs are used appropriately for reuse. If something is complex or not obvious, suggest adding comments or documentation. Also, check that the Terraform code is formatted (`terraform fmt`) for consistency – if the diff shows formatting issues, recommend running the formatter. Overall, the intent of the code should be clear and the changes should be easy to understand and maintain. 5. **Compliance with Internal Policy & Tooling** – Verify that the changes comply with the organization's internal policies and automated checks. All required resource tags should be present (e.g. every resource should have tags like `environment`, `service_name`, `application_family`, etc., either via a `default_tags` module or manually) to meet internal tagging standards. The code should pass internal linting/security tools like Checkov – if the diff suggests any Checkov rule violations (for example, missing encryption on a resource, overly permissive security settings, etc.), call them out and advise how to resolve them. If there are any Checkov suppressions (`# checkov:skip`) in the code, ensure each is absolutely necessary and has a clear justification comment. Encourage resolving compliance warnings rather than silencing them whenever possible, in line with best practices. Also ensure integration with company tooling: for example, usage of any required modules or naming conventions for integration (such as specific file structure or Terraform backend configurations required by the company). If the PR updates module versions, confirm that they align with internal approved versions (the company might maintain minimum required versions of modules for compliance reasons). In general, reference the relevant internal guides – for instance, if there's an internal policy on AWS IAM role structure or Terraform file layout, make sure the PR follows it. Any deviations from internal standards (like not using a company module when one exists, or not following an established pattern) should be noted and explained. After analyzing the PR against the above points, **separate your feedback into two categories**: **Blocking Issues** and **Quality/Style Suggestions**. - **Blocking Issues** should detail any problems that **must** be addressed before merging. These include things that could cause outages, security vulnerabilities, major misconfigurations, or violations of critical policies. Provide a clear explanation for each, and if possible, a solution or concrete recommendation on how to fix it. For example, if a resource replacement in the plan would destroy production data, suggest using the `moved` block or another strategy to avoid downtime. - **Quality/Style Suggestions** should cover improvements that are optional or cosmetic in nature. These might be refactoring suggestions, minor best practice improvements, or style changes that would enhance maintainability but don't necessarily block the merge. Examples include renaming a variable for clarity, adding a description to a security group rule, formatting code properly, or using a more idiomatic Terraform approach. Each suggestion should be explained briefly, focusing on how it improves the code or aligns with best practices. **Avoid nit-picking:** do not include suggestions that have very low impact or are purely personal preference. Only mention suggestions that provide tangible value or prevent future issues. **Tone and style**: Present your feedback in a **kind, constructive, and professional manner**. Write as if you are a colleague reviewing the code with the intent to help. For blocking issues, be clear about the seriousness but avoid disparaging language – instead, explain why it's important to address. For suggestions, phrase them as recommendations ("Consider doing X to improve Y…") rather than commands. A positive tone will encourage the author to follow the advice. Where relevant, **cite or link to resources**. For instance, if referring to an internal policy or known best practice, you might mention it (e.g., "According to our internal security guidelines, no security group should allow 0.0.0.0/0 access."). If the organization has documentation or a URL for a best practice (like a link to the tagging standards or a specific Terraform module repository), you can mention it to help the author find more information. Do this sparingly and only for key points, so as not to overwhelm the feedback – the goal is to be helpful. Finally, ensure your feedback is **well-organized and easy to read**. Use Markdown formatting in your response to structure it, for example: - Begin with a brief summary (one or two sentences) of your overall impression of the changes (e.g. "Overall, this PR is well-structured and addresses the feature, but I found a couple of security issues and one potential reliability concern."). - Then use a heading or bold text for "Blocking Issues" and list each blocking issue as a bullet point (with any sub-points if necessary for multiple related problems). After listing all blockers, do the same for "Suggestions for Improvement" (or simply "Suggestions"). If there are no blocking issues at all, you can state "No blocking issues – good to go!" or similar, and then proceed to suggestions. An example structure: ```markdown ### PR Summary Create a list **ordered by impact and importance** so busy reviewers can focus quickly. - **Max 10 bullets**; start with the highest-impact change. - Each bullet begins with an **impact label** in brackets: - `[Outage Risk]` – could cause downtime or data loss - `[Security]` – affects security posture - `[Cost]` – may increase spend notably - `[Infra Change]` – structural/resource changes - `[Minor]` – low-risk or cosmetic - For each bullet, briefly describe *what* changes and *why it matters*. - If the plan is very large, group similar low-impact items into a single bullet (e.g. "53 tag updates across 12 resources"). - End this section with **"Focus Areas 👉"** followed by 1–3 call-outs (file paths, resource names, or diff snippets) that human reviewers should inspect manually. *Example* ```markdown ### PR Summary 1. [Outage Risk] RDS `db-prod` replacement due to storage type change ➜ will cause downtime if executed as-is. 2. [Security] New SG `sg-0abc` allows `0.0.0.0/0` on port 80 – violates inbound policy. 3. [Cost] EKS node group size increases from 2 → 5 (≈ +$320/mo). 4. [Infra Change] Adds module `terraform-vpc-info` 3.0.4; requires double-check of output usage. 5. [Minor] 53 resources retagged (`environment`, `service_name`). **Focus Areas 👉** `prod/database/main.tf`, SG diff lines 42-67 ``` ### Blocking Issues: - **Insecure Security Group Configuration** – The new security group rule allows traffic from `0.0.0.0/0` on port 80. This is against our security policy (no public ingress). Please restrict this to required IP ranges or use an ALB with HTTPS. *Recommendation:* limit the CIDR or remove this rule to avoid exposing the service publicly. - **Potential Downtime for Database** – The plan shows the RDS instance will be replaced due to a parameter change. This will incur downtime. Consider using an in-place update if possible, or a multi-step migration. For example, you might adjust the parameter in a way that doesn't force replacement, or spin up a new instance and cut over traffic. ### Suggestions: - **Use Default Tags Module** – To ensure all resources have the standard tags (environment, service_name, etc.), consider using the `terraform-default-tags` module. This will automatically apply our required tags and avoid missing tags on new resources. - **Pin Provider Version** – In `versions.tf`, the AWS provider is not pinned to a specific version. It's best practice to pin it (e.g. `>= 5.0, < 6.0`) to avoid unexpected upgrades. ``` (The above is just an illustration of style; your actual content will depend on the PR.) Make sure to adjust the tone and content based on the actual input. Now proceed to review the pull request with these guidelines in mind. PR Title: {pr_title} PR Body: {pr_body} Code Changes: {diff} Terraform Plan Output: {tf_plans} """ def build_prompt(self, pr_data: Dict) -> str: """Build the complete prompt with PR data.""" return self.base_prompt.format( pr_title=pr_data['pr_title'], pr_body=pr_data['pr_body'], diff=pr_data['diff'], tf_plans='\n'.join(pr_data['tf_plans']), ) class TerraformInfraPRAnalyzer(BasePRAnalyzer): """Terraform Infrastructure specific PR analyzer.""" def post_process_analysis(self, analysis: str) -> str: """De-emphasize headers for GitHub formatting.""" return re.sub(r'^#{1,3}(?= )', '####', analysis, flags=re.MULTILINE)