How to address IaC shortcomings – Part 6b?
A previous article discussed a resolution to IaC shortcomings for declaring
resources with configuration not yet supported by an IaC repository. This
article discusses irreversible changes and manual intervention for certain Iac deployments.
IaC is an agreement between the IaC provider and the resource
provider. An attribute of a resource can only be applied when the IaC-provider
applies it in the way the resource provider expects and the resource-provider
provisions in the way that the IaC provider expects. In many cases, this is
honored but some attributes can get out of sync resulting in unsuccessful
deployments of what might seem to be correct declarations.
One of
the limitations is when one resource is created as part of the configuration of
another resource and there is an association formed between the two resources.
It should be possible to reverse the rollout by disassociating the resources
before deleting the one that was created. However, sometimes the associations
cannot be broken by IaC or by actions on the management portal for the
resources. Other forms of management such as the Azure CLI command must be
used. In such cases, manual intervention or introduction of logic in the pipeline
to break the impasse is required. Only by the
mitigation and running the IaC twice, once to detect the conflict for the
existing resources and second to reset the configuration, will the IaC start
succeeding in subsequent deployments.
The destroy of an existing resource and the creation of a new
resource is also required to keep the state in sync with the IaC. If the
resource is being missed from the state, it might be interpreted as a resource
that was not there in the IaC to begin with and require the destroy before the
IaC recognized creation occurs.
It is possible to make use of the best of both worlds with a
folder structure that separates the Terraform templates into a folder called
‘module’ and the resource provider templates in another folder at the same
level and named something like ‘subscription-deployments’ which includes native
blueprints and templates. The GitHub workflow definitions will leverage proper
handling of either location or trigger the workflow on any changes to either of
these locations.
The native support for extensibility depends on naming and
logic.
Naming is facilitated with canned prefixes/suffixes and dynamic
random string to make each rollout independent of the previous. Some examples
include:
resource "random_string" "unique" {
count = var.enable_static_website &&
var.enable_cdn_profile ? 1 : 0
length = 8
special = false
upper = false
}
Logic can be written out with PowerShell for Azure public cloud
which is the de facto standard for automation language. Then a pseudo resource
can be added using this logic as follows:
resource "null_resource" "add_custom_domain" {
count = var.custom_domain_name != null ? 1 : 0
triggers = { always_run = timestamp() }
depends_on = [
azurerm_app_service.web-app
]
provisioner "local-exec" {
command = "pwsh
${path.module}/Setup-AzCdnCustomDomain.ps1"
environment = {
CUSTOM_DOMAIN
= var.custom_domain_name
RG_NAME =
var.resource_group_name
FRIENDLY_NAME = var.friendly_name
STATIC_CDN_PROFILE =
var.cdn_profile_name
}
}
}
PowerShell scripts can help with both the deployment as well as
the pipeline automations. There are a few caveats with scripts because the
general preference is for declarative and idempotent IaC rather than script so
extensibility must be given the same due consideration as customization.
All scripts can be stored in folders with names ending with
‘scripts’.
These are sufficient to address the above-mentioned
shortcomings in the Infrastructure-as-Code.
Terraform and discusses the order and repetition involved in IaC
deployments.
IaC is an agreement between the IaC provider and the resource
provider. An attribute of a resource can only be applied when the IaC-provider
applies it in the way the resource provider expects and the resource-provider
provisions in the way that the IaC provider expects. In many cases, this is
honored but some attributes can get out of sync resulting in unsuccessful
deployments of what might seem to be correct declarations.
For instance, some attributes of a resource can be specified via
the IaC provider but go completely ignored by the resource provider. If there
are two attributes that can be specified, the resource-provider reserves the
right to prioritize one over the other. Even when a resource attribute is
correctly specified, the resource provider could mandate the destroy of
existing resource and the creation of a new resource. A more common case
is one when where the IaC wants to add a new property for all resources of a
specific resource type but there are already existing resources that do not
have that property initialized. In such a case, the applying of the IaC change
to add a new property will fail for existing instances but succeed for the new
instances. Only by running the IaC twice, once to detect the missing property
for the existing resources and initialize and second to correctly report the new
property, will the IaC start succeeding in subsequent deployments.
The destroy of an existing resource and the creation of a new
resource is also required to keep the state in sync with the IaC. If the resource
is being missed from the state, it might be interpreted as a resource that was
not there in the IaC to begin with and require the destroy before the IaC
recognized creation occurs.
It is possible to make use of the best of both worlds with a folder
structure that separates the Terraform templates into a folder called ‘module’
and the resource provider templates in another folder at the same level and
named something like ‘subscription-deployments’ which includes native
blueprints and templates. The GitHub workflow definitions will leverage proper handling
of either location or trigger the workflow on any changes to either of these
locations.
The native support for extensibility depends on naming and
logic.
Naming is facilitated with canned prefixes/suffixes and dynamic
random string to make each rollout independent of the previous. Some examples
include:
resource "random_string" "unique" {
count = var.enable_static_website &&
var.enable_cdn_profile ? 1 : 0
length = 8
special = false
upper = false
}
Logic can be written out with PowerShell for Azure public cloud
which is the de facto standard for automation language. Then a pseudo resource
can be added using this logic as follows:
resource "null_resource" "add_custom_domain" {
count = var.custom_domain_name != null ? 1 : 0
triggers = { always_run = timestamp() }
depends_on = [
azurerm_app_service.web-app
]
provisioner "local-exec" {
command = "pwsh
${path.module}/Setup-AzCdnCustomDomain.ps1"
environment = {
CUSTOM_DOMAIN = var.custom_domain_name
RG_NAME =
var.resource_group_name
FRIENDLY_NAME = var.friendly_name
STATIC_CDN_PROFILE =
var.cdn_profile_name
}
}
}
PowerShell scripts can help with both the deployment as well as
the pipeline automations. There are a few caveats with scripts because the
general preference is for declarative and idempotent IaC rather than script so
extensibility must be given the same due consideration as customization.
All scripts can be stored in folders with names ending with
‘scripts’.
These are sufficient to address the above-mentioned
shortcomings in the Infrastructure-as-Code.
No comments:
Post a Comment