Skip to content

Latest commit

 

History

History
81 lines (71 loc) · 8.81 KB

File metadata and controls

81 lines (71 loc) · 8.81 KB

SCOPE — terraform-azurerm-container-group

Design intent

Manages an Azure Container Instances container group. The single resource azurerm_container_group is named this. Secure by default: the empty (minimal) call yields a hardened resource with no inbound IP address, and every relaxation — public exposure, a privileged container, embedded registry credentials — is an explicit caller opt-in. This is a standalone primitive; cross-cutting concerns (the resource group, the registry the images come from, the VNet subnet for private injection, the managed identity used to pull, and the Log Analytics workspace for diagnostics) are owned by sibling modules and consumed here by id / name / key.

In scope

  • azurerm_container_group — a single resource named this, rendering:
    • one or more container blocks (a keyed map so a container can be added or removed without re-indexing);
    • optional init_container blocks;
    • an optional identity block (system- and/or user-assigned managed identity);
    • optional image_registry_credential blocks for private-registry pulls;
    • an optional diagnostics block shipping container logs to Log Analytics;
    • an optional dns_config block;
    • nested ports, liveness_probe, readiness_probe, security, volume (with git_repo) blocks per container.

Out of scope / consumed by id

  • The resource group — owned by terraform-azurerm-resource-group; consumed by name.
  • The container registry the images are pulled from — owned by terraform-azurerm-container-registry; the login server is referenced in image / image_registry_credentials[*].server.
  • The user-assigned identity used for identity-based ACR pulls and CMK access — owned by terraform-azurerm-user-assigned-identity; consumed by id.
  • The subnet for private VNet injection — owned by terraform-azurerm-virtual-network / a subnet module; consumed by id via subnet_ids.
  • The Log Analytics workspace for diagnostics — owned by terraform-azurerm-log-analytics-workspace; consumed by its workspace ID and shared key.
  • The Key Vault key for customer-managed-key encryption — owned by terraform-azurerm-key-vault; consumed by key_vault_key_id.

Consumes

Input Type Source module
resource_group_name string terraform-azurerm-resource-group (name)
location string caller / terraform-azurerm-resource-group (location)
subnet_ids set(string) terraform-azurerm-virtual-network (subnet id)
identity.identity_ids / image_registry_credentials[*].user_assigned_identity_id string terraform-azurerm-user-assigned-identity (id)
diagnostics.log_analytics.workspace_id string terraform-azurerm-log-analytics-workspace (workspace_id)
key_vault_key_id string terraform-azurerm-key-vault (key id)

🔑 Required Azure RBAC Roles / Permissions

  • Create/manage the container group: Contributor on the target resource group, or a custom role granting Microsoft.ContainerInstance/containerGroups/* scoped to the resource group.
  • Private VNet injection (ip_address_type = "Private"): Network Contributor (or Microsoft.Network/virtualNetworks/subnets/join/action) on the target subnet.
  • Identity-based image pulls: the user-assigned identity referenced for the pull needs AcrPull on the source registry. The deploying principal that assigns the identity to the group needs Managed Identity Operator on that identity.
  • Customer-managed-key encryption: the identity in key_vault_user_assigned_identity_id needs get/wrapKey/unwrapKey on the Key Vault key (Key Vault Crypto Service Encryption User under RBAC authorization).

Azure Prerequisites

  • An existing resource group in a supported US Azure region.
  • The Microsoft.ContainerInstance resource provider registered on the target subscription.
  • For private injection: an existing, delegated subnet (Microsoft.ContainerInstance/containerGroups delegation) in the same region.
  • For identity-based pulls: an existing user-assigned identity with AcrPull on the registry.
  • For diagnostics: an existing Log Analytics workspace and its shared key, provisioned out of band.
  • The caller configures the provider "azurerm" { features {} } block, auth, and subscription; the module declares none of these.

Emits

Output Description Kind
id The Azure Resource ID of the container group Passthrough
name The name of the container group Passthrough
location Azure region the resource is deployed in, in the canonical form Azure uses Passthrough
ip_address The IP address allocated to the container group (empty when ip_address_type is "None") Passthrough
fqdn The public fully-qualified domain name of the container group (set only when a dns_name_label is used with a public IP) Passthrough
identity_principal_id Principal (object) ID of the container group's managed identity, or null when no identity is configured Derived
identity_tenant_id Tenant ID of the container group's managed identity, or null when no identity is configured Derived
dns_label_is_reusable_by_anyone True when this group publishes a DNS label AND leaves its reuse policy at Azure's default, which is Unsecure - the least restrictive of five values, meaning ANYONE in ANY tenant may claim the label once this group is deleted Derived
key_rotation_requires_replacing_the_group True when customer-managed-key encryption is configured, and it carries a consequence that differs from the sibling modules in this suite Derived
is_publicly_reachable True when the group holds a public IP address Derived
restart_policy_will_rerun_a_completed_job True when the group restarts its containers on any exit, including a successful one - which is the default, and the wrong choice for a run-to-completion job Derived
is_evictable_spot_capacity True when the group runs on Spot capacity, which is cheaper and can be evicted at any time with no error Terraform will report Derived
spot_and_ip_address_are_mutually_exclusive Always true, and the rule lives where a schema search will not find it Constant
name_is_not_pattern_checked_by_the_provider Always true Constant
network_profile_id_is_deliberately_not_exposed Always true, and it is a decision rather than an omission Constant

No plaintext secret is emitted. Secret-bearing inputs (secure_environment_variables, image_registry_credentials[*].password, volumes[*].storage_account_key, volumes[*].secret, diagnostics.log_analytics.workspace_key) are redacted by the provider's attribute-level sensitivity; none is echoed in an output.

Provider gotchas

  • The container group is effectively immutable. Changing name, resource_group_name, location, os_type, sku, zones, subnet_ids, restart_policy, priority, the dns_name_label, or any container / init_container definition forces the whole group to be replaced. Confirmed against the live provider schema.
  • At least one container is required; the type contract enforces this with a containers length validation before any API call.
  • ip_address_type = "Private" requires subnet_ids and forbids a dns_name_label; ip_address_type = "Public" is what a dns_name_label and a public FQDN attach to; ip_address_type = "None" (the default) exposes no inbound IP.
  • dns_name_label is only valid with a public IP, and dns_name_label_reuse_policy only applies when a label is set.
  • Secret-bearing fields are marked sensitive at the provider attribute level, not the variable level: marking the enclosing containers / image_registry_credentials / diagnostics variables sensitive would make them unusable as for_each / dynamic sources, so this module relies on the provider's attribute-level redaction and documents out-of-band provisioning instead.
  • The provider will not initialize without a caller-side features {} block; that belongs to the root module, not here.

Design decisions

  • Per this module suite's single-primary-resource convention, the resource is named this.
  • Per this suite's secure-by-default convention, the empty call produces the hardened resource: ip_address_type defaults to "None" (no inbound exposure), container security.privilege_enabled defaults to false, and identity-based registry pulls are preferred over embedded credentials. Each relaxation (public exposure, a privileged container, a registry password) is an explicit caller opt-out.
  • Per this suite's keyed-collection convention, containers, init_containers, image_registry_credentials, per-container ports, and per-container volumes are keyed maps so adding or removing one entry never re-indexes the rest.
  • These are this module suite's conventions; all argument facts are confirmed against the live provider schema.