Skip to content

Conversation

@spy86
Copy link
Member

@spy86 spy86 commented Aug 4, 2025

Summary by CodeRabbit

  • New Features

    • Expanded configuration options for Azure Container Registry, including advanced features such as georeplication, network rules, retention policies, trust policies, managed identities, and encryption.
    • Added new variables to enable or disable features like public network access, quarantine policy, zone redundancy, export policy, anonymous pull, and data endpoint.
    • Enhanced support for Premium SKU capabilities.
  • Bug Fixes

    • Output values for admin username and password now return null when the admin account is disabled, improving output accuracy.
  • Documentation

    • Improved variable descriptions and added validation for input values to enhance usability and robustness.

@coderabbitai
Copy link

coderabbitai bot commented Aug 4, 2025

Warning

Rate limit exceeded

@spy86 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 34 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 1f0c248 and 9d30537.

📒 Files selected for processing (5)
  • README.md (1 hunks)
  • acr.tf (1 hunks)
  • pipelines/.terraform-docs.yaml (1 hunks)
  • pipelines/azure-pipelines-pr.yaml (2 hunks)
  • variables.tf (1 hunks)

Walkthrough

The changes significantly expand the configuration and feature set for an Azure Container Registry Terraform module. The resource definition, variables, and outputs are refactored to support advanced options such as georeplication, network rules, policies, identities, and encryption. Numerous new variables and dynamic blocks are introduced to enable conditional and complex configurations, especially for Premium SKU features.

Changes

Cohort / File(s) Change Summary
Resource Expansion
acr.tf
The azurerm_container_registry.main resource is restructured with new and updated attributes, dynamic blocks for advanced features (georeplication, network rules, retention, trust policy, identity, encryption), and expanded conditional logic for configuration.
Variable Enhancements
variables.tf
Extensive reorganization and addition of variables to support new features; includes validation, default values, and complex object types for advanced configuration (e.g., georeplications, network rules, policies, identity, encryption).
Output Refinements
output.tf
Output blocks for admin credentials are made conditional on admin account status, with sensitivity flags updated and minor formatting improvements; two new outputs added for data endpoint hostnames and managed identity details.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Terraform
    participant AzureRM

    User->>Terraform: Configure variables (including advanced features)
    Terraform->>AzureRM: Create/Update azurerm_container_registry with dynamic blocks
    AzureRM-->>Terraform: Provisioned Container Registry (with optional features)
    Terraform-->>User: Output admin credentials and registry info (conditionally)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐇
In the garden of code, new options now bloom,
With georeplication and rules to consume.
Policies, identities, encryption—oh my!
This registry’s features now reach for the sky.
Hopping through variables, outputs refined,
A richer ACR, robustly designed!

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch patch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
variables.tf (3)

16-23: Make SKU validation case-insensitive.

Users often pass "premium" or "STANDARD". contains() is case-sensitive, so the current rule will reject otherwise valid input.

-  validation {
-    condition     = contains(["Basic", "Standard", "Premium"], var.acr_tier)
-    error_message = "The SKU must be one of: Basic, Standard, Premium."
-  }
+  validation {
+    condition     = contains(["basic", "standard", "premium"], lower(var.acr_tier))
+    error_message = "The SKU must be one of: Basic, Standard, Premium (case-insensitive)."
+  }

68-76: Apply the same case-insensitive pattern to network_rule_bypass_option.

Keeps behaviour consistent across variables and avoids needless errors.


89-97: Consider IP/CIDR validation for network_rule_set.ip_rules.

Passing an invalid IP string will only surface during apply. A simple regex or can(cidrhost())-based test can catch formatting mistakes early.

acr.tf (1)

71-77: Encryption block requires Premium SKU & Customer-Managed Key prerequisites.

Provider will reject this block unless:

  1. sku is Premium
  2. The Key Vault key has crypto permissions granted to the registry’s identity.

Consider adding documentation or validation to prevent mis-configuration.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f835fcf and 6cc143d.

📒 Files selected for processing (3)
  • acr.tf (1 hunks)
  • output.tf (1 hunks)
  • variables.tf (1 hunks)
🧰 Additional context used
🪛 Checkov (3.2.334)
acr.tf

[MEDIUM] 1-80: Enable vulnerability scanning for container images.

(CKV_AZURE_163)


[MEDIUM] 1-80: Ensure geo-replicated container registries to match multi-region container deployments.

(CKV_AZURE_165)


[MEDIUM] 1-80: Ensures that ACR uses signed/trusted images

(CKV_AZURE_164)

🔇 Additional comments (2)
variables.tf (1)

116-123: Validate identity.type against provider-supported values.

SystemAssigned, UserAssigned, or SystemAssigned, UserAssigned are the only accepted strings. Add a validation block to fail fast on typos.

acr.tf (1)

31-45: Null-safe loops for empty IP/VNet rule lists.

If ip_rules or virtual_network_rules is null, Terraform will error with “Invalid for_each argument”. Use toset() or a coalesce to empty list.

-for_each = network_rule_set.value.ip_rules
+for_each = network_rule_set.value.ip_rules != null ? network_rule_set.value.ip_rules : []

Apply the same pattern to virtual_network_rules.

acr.tf Outdated
Comment on lines 15 to 23
dynamic "georeplication" {
for_each = var.georeplications
content {
location = georeplication.value.location
zone_redundancy_enabled = georeplication.value.zone_redundancy_enabled
regional_endpoint_enabled = georeplication.value.regional_endpoint_enabled
tags = merge(var.default_tags, georeplication.value.tags)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Guard georeplication against non-Premium SKUs.

georeplication is only valid when sku = "Premium". Without a conditional, a non-Premium deploy will fail.

-for_each = var.georeplications
+for_each = var.acr_tier == "Premium" ? var.georeplications : []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dynamic "georeplication" {
for_each = var.georeplications
content {
location = georeplication.value.location
zone_redundancy_enabled = georeplication.value.zone_redundancy_enabled
regional_endpoint_enabled = georeplication.value.regional_endpoint_enabled
tags = merge(var.default_tags, georeplication.value.tags)
}
}
dynamic "georeplication" {
- for_each = var.georeplications
+ for_each = var.acr_tier == "Premium" ? var.georeplications : []
content {
location = georeplication.value.location
zone_redundancy_enabled = georeplication.value.zone_redundancy_enabled
regional_endpoint_enabled = georeplication.value.regional_endpoint_enabled
tags = merge(var.default_tags, georeplication.value.tags)
}
}
🤖 Prompt for AI Agents
In acr.tf around lines 15 to 23, the georeplication block is applied
unconditionally, but it should only be included when the SKU is "Premium". Add a
conditional expression to the dynamic "georeplication" block to ensure it only
executes if var.sku equals "Premium", preventing deployment failures for
non-Premium SKUs.

Comment on lines 13 to 17
output "admin_username" {
description = "The Username associated with the Container Registry Admin account - if the admin account is enabled."
value = azurerm_container_registry.main.admin_username
sensitive = true
value = azurerm_container_registry.main.admin_enabled ? azurerm_container_registry.main.admin_username : null
sensitive = false
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

admin_username should still be marked sensitive.

Although a username is less critical than a password, Azure classifies it as sensitive and the provider already flags it so. Overriding it to false leaks the value into state diff, logs, and remote outputs.

-output "admin_username" {
-  description = "The Username associated with the Container Registry Admin account - if the admin account is enabled."
-  value       = azurerm_container_registry.main.admin_enabled ? azurerm_container_registry.main.admin_username : null
-  sensitive   = false
-}
+output "admin_username" {
+  description = "The Username associated with the Container Registry Admin account - if the admin account is enabled."
+  value       = azurerm_container_registry.main.admin_enabled ? azurerm_container_registry.main.admin_username : null
+  sensitive   = true
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
output "admin_username" {
description = "The Username associated with the Container Registry Admin account - if the admin account is enabled."
value = azurerm_container_registry.main.admin_username
sensitive = true
value = azurerm_container_registry.main.admin_enabled ? azurerm_container_registry.main.admin_username : null
sensitive = false
}
output "admin_username" {
description = "The Username associated with the Container Registry Admin account - if the admin account is enabled."
value = azurerm_container_registry.main.admin_enabled ? azurerm_container_registry.main.admin_username : null
sensitive = true
}
🤖 Prompt for AI Agents
In output.tf around lines 13 to 17, the output "admin_username" is incorrectly
marked as not sensitive, which can expose sensitive information in state files
and logs. Change the sensitive attribute from false to true to ensure the
username is treated as sensitive and properly protected.

Comment on lines +44 to +66
variable "zone_redundancy_enabled" {
description = "Whether zone redundancy is enabled for the Container Registry (Premium SKU only)."
type = bool
default = false
}

variable "export_policy_enabled" {
description = "Whether export policy is enabled for the Container Registry."
type = bool
default = true
}

variable "anonymous_pull_enabled" {
description = "Whether anonymous pull access is enabled for the Container Registry (Premium SKU only)."
type = bool
default = false
}

variable "data_endpoint_enabled" {
description = "Whether data endpoint is enabled for the Container Registry (Premium SKU only)."
type = bool
default = false
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation to block Premium-only flags when acr_tier ≠ "Premium".

zone_redundancy_enabled, anonymous_pull_enabled, and data_endpoint_enabled are only accepted by the provider when the registry SKU is Premium.
Turning any of them on while var.acr_tier is Basic/Standard will make the plan/apply fail.

 variable "zone_redundancy_enabled" {
   description = "Whether zone redundancy is enabled for the Container Registry (Premium SKU only)."
   type        = bool
   default     = false
+  validation {
+    condition     = !(var.zone_redundancy_enabled && var.acr_tier != "Premium")
+    error_message = "zone_redundancy_enabled can only be true when acr_tier is \"Premium\"."
+  }
 }

Replicate the same conditional check for the other Premium-only switches to fail fast and make the UX explicit.

🤖 Prompt for AI Agents
In variables.tf between lines 44 and 66, add validation blocks to the variables
zone_redundancy_enabled, anonymous_pull_enabled, and data_endpoint_enabled to
ensure they can only be true if var.acr_tier is "Premium". Implement a condition
in each variable's validation that returns an error message if the variable is
true while var.acr_tier is not "Premium", thereby preventing invalid
configurations early during plan/apply.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (2)
acr.tf (1)

17-25: Georeplication still unguarded for non-Premium SKU
The georeplications block will make plan/apply fail when var.acr_tier"Premium". Wrap the for_each with an SKU check, as suggested previously.

-for_each = var.georeplications
+for_each = var.acr_tier == "Premium" ? var.georeplications : []
variables.tf (1)

44-66: Missing validation for Premium-only switches
zone_redundancy_enabled, anonymous_pull_enabled, and data_endpoint_enabled remain unchecked against var.acr_tier. Add the validation blocks recommended in the earlier review so invalid combos fail fast.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cc143d and 1f0c248.

📒 Files selected for processing (3)
  • acr.tf (1 hunks)
  • output.tf (1 hunks)
  • variables.tf (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • output.tf
🧰 Additional context used
🪛 Checkov (3.2.334)
acr.tf

[MEDIUM] 1-67: Enable vulnerability scanning for container images.

(CKV_AZURE_163)


[MEDIUM] 1-67: Ensure geo-replicated container registries to match multi-region container deployments.

(CKV_AZURE_165)


[MEDIUM] 1-67: Ensures that ACR uses signed/trusted images

(CKV_AZURE_164)

acr.tf Outdated
Comment on lines 14 to 15
retention_policy_in_days = var.retention_policy != null ? var.retention_policy.days : null
trust_policy_enabled = var.trust_policy != null ? var.trust_policy.enabled : false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Retention & Trust policy attributes will fail plan – use proper nested blocks
retention_policy_in_days and trust_policy_enabled are not valid top-level arguments for azurerm_container_registry. In addition, var.retention_policy is declared as a number, so the .days accessor will raise a type error. Switch to the provider-expected nested blocks (and align variable types) to avoid a hard failure at terraform plan.

-  retention_policy_in_days      = var.retention_policy != null ? var.retention_policy.days : null
-  trust_policy_enabled          = var.trust_policy != null ? var.trust_policy.enabled : false
+
+  dynamic "retention_policy" {
+    for_each = var.retention_policy != null ? [var.retention_policy] : []
+    content {
+      days   = retention_policy.value.days
+      status = "Enabled"
+    }
+  }
+
+  dynamic "trust_policy" {
+    for_each = var.trust_policy != null ? [var.trust_policy] : []
+    content {
+      enabled = trust_policy.value.enabled
+    }
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
retention_policy_in_days = var.retention_policy != null ? var.retention_policy.days : null
trust_policy_enabled = var.trust_policy != null ? var.trust_policy.enabled : false
dynamic "retention_policy" {
for_each = var.retention_policy != null ? [var.retention_policy] : []
content {
days = retention_policy.value.days
status = "Enabled"
}
}
dynamic "trust_policy" {
for_each = var.trust_policy != null ? [var.trust_policy] : []
content {
enabled = trust_policy.value.enabled
}
}
🤖 Prompt for AI Agents
In acr.tf around lines 14 to 15, the attributes retention_policy_in_days and
trust_policy_enabled are incorrectly used as top-level arguments and
var.retention_policy is a number, causing type errors. Replace these with the
correct nested blocks for retention_policy and trust_policy as expected by the
azurerm_container_registry resource, and update the variable types accordingly
to match the nested block structure to prevent terraform plan failures.

Comment on lines +58 to +64
dynamic "encryption" {
for_each = var.encryption != null ? [var.encryption] : []
content {
key_vault_key_id = encryption.value.key_vault_key_id
identity_client_id = encryption.value.identity_client_id
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Premium-only encryption block needs an SKU gate
encryption is accepted only on Premium registries. Protect the dynamic block so Basic/Standard deployments remain valid.

-for_each = var.encryption != null ? [var.encryption] : []
+for_each = var.acr_tier == "Premium" && var.encryption != null ? [var.encryption] : []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dynamic "encryption" {
for_each = var.encryption != null ? [var.encryption] : []
content {
key_vault_key_id = encryption.value.key_vault_key_id
identity_client_id = encryption.value.identity_client_id
}
}
dynamic "encryption" {
- for_each = var.encryption != null ? [var.encryption] : []
+ for_each = var.acr_tier == "Premium" && var.encryption != null ? [var.encryption] : []
content {
key_vault_key_id = encryption.value.key_vault_key_id
identity_client_id = encryption.value.identity_client_id
}
}
🤖 Prompt for AI Agents
In acr.tf around lines 58 to 64, the dynamic "encryption" block must be
conditionally included only for Premium SKU registries. Add a condition to check
if the SKU is Premium before including the encryption block, ensuring Basic and
Standard SKUs do not attempt to use encryption and cause deployment errors.

Comment on lines +78 to +87
variable "georeplications" {
description = "A list of georeplication configurations for the Container Registry (Premium SKU only)."
type = list(object({
location = string
zone_redundancy_enabled = bool
regional_endpoint_enabled = bool
tags = map(string)
}))
default = []
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Guard georeplication variable against non-Premium usage
As with the resource block, the variable should surface an explicit validation that forbids non-empty georeplications when acr_tier is not "Premium". This prevents silent misconfiguration at module entry.

🤖 Prompt for AI Agents
In variables.tf around lines 78 to 87, add a validation block to the
georeplications variable that checks if acr_tier is "Premium" when
georeplications is not empty. This validation should produce an error if
georeplications is set but acr_tier is not "Premium", preventing
misconfiguration. Use Terraform's variable validation syntax to enforce this
condition explicitly.

Comment on lines 90 to 97
type = object({
default_action = string
ip_rules = list(string)
virtual_network_rules = list(string)
})
default = null
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Network rule set needs SKU validation
network_rule_set is not supported on Basic/Standard SKUs. Add a validation similar to:

validation {
  condition     = var.network_rule_set == null || var.acr_tier == "Premium"
  error_message = "network_rule_set can only be set when acr_tier is \"Premium\"."
}
🤖 Prompt for AI Agents
In variables.tf around lines 90 to 97, the network_rule_set variable lacks SKU
validation and is not supported on Basic/Standard SKUs. Add a validation block
to ensure network_rule_set is either null or acr_tier is "Premium". This
involves adding a validation condition that checks if var.network_rule_set is
null or var.acr_tier equals "Premium", and an error_message stating that
network_rule_set can only be set when acr_tier is "Premium".

Comment on lines +99 to +103
description = "Number of days to retain untagged manifests in the Container Registry (Premium SKU only). Set to null to disable."
type = number
default = null
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Variable shape does not match usage – switch to an object
acr.tf expects a .days field, but the variable is defined as a plain number. This type mismatch will break the module. Define the variable as an object with a days attribute (or change the usage).

-variable "retention_policy" {
-  description = "Number of days to retain untagged manifests in the Container Registry (Premium SKU only). Set to null to disable."
-  type = number
-  default = null
-}
+variable "retention_policy" {
+  description = "Retention policy configuration for untagged manifests (Premium SKU only)."
+  type = object({
+    days = number
+  })
+  default = null
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In variables.tf around lines 99 to 103, the variable "retention_policy" is
defined as a number but is used in acr.tf expecting an object with a "days"
field. To fix this, redefine "retention_policy" as an object type with a "days"
attribute instead of a plain number, ensuring the variable shape matches its
usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant