Cannot create azure ad application with oauth via terraform - azure

Im trying to create/register application in Azure AD with oauth2_permissions / scopes.
Im following this documentatino page to do so: https://www.terraform.io/docs/providers/azuread/r/application.html
And I have reduced it to that simple .tf file:
provider "azuread" {
version = "=0.7.0"
subscription_id = "*******************************"
tenant_id = var.tenant-id
}
resource "azuread_application" "example" {
name = "example"
// oauth2_permissions {
// admin_consent_description = "Allow the application to access example on behalf of the signed-in user."
// admin_consent_display_name = "Access example"
// is_enabled = true
// type = "User"
// user_consent_description = "Allow the application to access example on your behalf."
// user_consent_display_name = "Access example"
// value = "user_impersonation"
// }
}
Running script like this with terraform plan says:
C:\source\ITAN\terraform (master -> origin) λ terraform plan
Refreshing Terraform state in-memory prior to plan... The refreshed
state will be used to calculate this plan, but will not be persisted
to local or remote state storage.
An execution plan has been generated and is shown below. Resource
actions are indicated with the following symbols: + create
Terraform will perform the following actions:
azuread_application.example will be created + resource
azuread_application" "example" {
+ application_id = (known after apply)
+ homepage = (known after apply)
+ id = (known after apply)
+ identifier_uris = (known after apply)
+ name = "example"
+ object_id = (known after apply)
+ owners = (known after apply)
+ public_client = (known after apply)
+ reply_urls = (known after apply)
+ type = "webapp/api"
+ oauth2_permissions {
+ admin_consent_description = (known after apply)
+ admin_consent_display_name = (known after apply)
+ id = (known after apply)
+ is_enabled = (known after apply)
+ type = (known after apply)
+ user_consent_description = (known after apply)
+ user_consent_display_name = (known after apply)
+ value = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Note: You didn't specify an "-out" parameter to save this plan, so
Terraform can't guarantee that exactly these actions will be performed
if "terraform apply" is subsequently run.
But when I uncomment the oauth2_permissions
provider "azuread" {
version = "=0.7.0"
subscription_id = "******************"
tenant_id = var.tenant-id
}
resource "azuread_application" "example" {
name = "example"
oauth2_permissions {
admin_consent_description = "Allow the application to access example on behalf of the signed-in user."
admin_consent_display_name = "Access example"
is_enabled = true
type = "User"
user_consent_description = "Allow the application to access example on your behalf."
user_consent_display_name = "Access example"
value = "user_impersonation"
}
}
Problem occurs and it states like this:
Error: "oauth2_permissions.0.user_consent_display_name": this field
cannot be set
on itan-azure-ad.tf line 7, in resource "azuread_application"
"example": 7: resource "azuread_application" "example" {
Any idea what am I doing wrong? Im logged in, I have selected proper subscription and switched to it. I own the azure account. I have created application via azure portal successully, yet I want to have it done automatically. Running on terraform:
terraform -v
Terraform v0.12.28
+ provider.azuread v0.7.0

Looks like it's not supported to set user_consent_display_name in the version provider.azuread v0.7.0. See oauth2_permissions in the change log here.
Please use the latest azuread provider version 0.11.0. It will fix your issue.
provider "azuread" {
version = "~>0.11.0"
subscription_id = "*******************************"
tenant_id = var.tenant-id
}

Related

How to use terraform depends_on to dictate ordering of resource creation?

I have the following terraform resources in a file
resource "google_project_service" "cloud_resource_manager" {
project = var.tf_project_id
service = "cloudresourcemanager.googleapis.com"
disable_dependent_services = true
}
resource "google_project_service" "artifact_registry" {
project = var.tf_project_id
service = "artifactregistry.googleapis.com"
disable_dependent_services = true
depends_on = [google_project_service.cloud_resource_manager]
}
resource "google_artifact_registry_repository" "el" {
provider = google-beta
project = var.tf_project_id
location = var.region
repository_id = "el"
description = "Repository for extract/load docker images"
format = "DOCKER"
depends_on = [google_project_service.artifact_registry]
}
However, when I run terraform plan, I get this
Terraform will perform the following actions:
# google_artifact_registry_repository.el will be created
+ resource "google_artifact_registry_repository" "el" {
+ create_time = (known after apply)
+ description = "Repository for extract/load docker images"
+ format = "DOCKER"
+ id = (known after apply)
+ location = "us-central1"
+ name = (known after apply)
+ project = "backbone-third-party-data"
+ repository_id = "el"
+ update_time = (known after apply)
}
# google_project_iam_member.ingest_sa_roles["cloudscheduler.serviceAgent"] will be created
+ resource "google_project_iam_member" "ingest_sa_roles" {
+ etag = (known after apply)
+ id = (known after apply)
+ member = (known after apply)
+ project = "backbone-third-party-data"
+ role = "roles/cloudscheduler.serviceAgent"
}
# google_project_iam_member.ingest_sa_roles["run.invoker"] will be created
+ resource "google_project_iam_member" "ingest_sa_roles" {
+ etag = (known after apply)
+ id = (known after apply)
+ member = (known after apply)
+ project = <my project id>
+ role = "roles/run.invoker"
}
# google_project_service.artifact_registry will be created
+ resource "google_project_service" "artifact_registry" {
+ disable_dependent_services = true
+ disable_on_destroy = true
+ id = (known after apply)
+ project = <my project id>
+ service = "artifactregistry.googleapis.com"
}
See how google_project_service.artifact_registry is created after google_artifact_registry_repository.el. I was hoping that my depends_on in resource google_artifact_registry_repository.el would make it so the service was created first. Am I misunderstanding how depends_on works? Or does the ordering of resources listed from terraform plan not actually mean that thats the order they are created in?
Edit: when I run terraform apply it errors out with
Error 403: Cloud Resource Manager API has not been used in project 521986354168 before or it is disabled
Even though it is enabled. I think it's doing this because its running the artifact registry resource creation before creating the terraform services?
I don't think that it will be possible to enable this particular API this way, as google_project_service resource depends on Resource Manager API (and maybe also on Service Usage API?) being enabled. So you could either enable those manually or use null_resource with local-exec provisioner to do it automatically:
resource "null_resource" "enable_cloudresourcesmanager_api" {
provisioner "local-exec" {
command = "gcloud services enable cloudresourcesmanager.googleapis.com cloudresourcemanager.googleapis.com --project ${var.project_id}"
}
}
Another issue you might find is that enabling an API takes some time, depending on a service. So sometimes even though your resources depend on a resource enabling an API, you will still get the same error message. Then you can just reapply your configuration and as an API had time to initialize, second apply will work. In some cases this is good enough, but if you are building a reusable module you might want to avoid those reapplies. Then you can use time_sleep resources to wait for API initialization:
resource "time_sleep" "wait_for_cloudresourcemanager_api" {
depends_on = [null_resource.enable_cloudresourcesmanager_api]
# or: depends_on = [google_project_service.some_other_api]
create_duration = "30s"
}

AzureAd application and password trying to add and destroy instead of change

I am having an issue with terraform plan for azuread_application, azuread_application_password and azuread_service_principal, always wants to destroy and create a new one, lots of values are being shown as (known after apply), surely as already exists should just show as change when any differences, here is an example for password:
+ resource "azuread_application_password" "local_app_password" {
+ application_object_id = (known after apply)
+ description = (known after apply)
+ end_date = "2030-01-01T00:00:00Z"
+ id = (known after apply)
+ key_id = (known after apply)
+ start_date = (known after apply)
+ value = (sensitive value)
}
Can anyone advise what causes this issue with terraform azure provider?

Why do I got NoSuchBucket: The specified bucket does not exist error?

I am newbee to Terraform world. I am following one tutorial,but I tried to implement AWS Provider Upgrade Guide Upgrade4.
Terraform apply gives me
│ Error: error creating S3 bucket ACL for kevindenotariis-simple-web-app-logs: NoSuchBucket: The specified bucket does not exist
│ status code: 404, request id: W5K3YPKHMN8YA458, host id: fH5xGgvTn8JfprqbaCsVCS/ICirJdVcDS9GOo8R7TFshS+UquH/Xy1n0ZcSdLgrdbRqFp4wFKzQ=
│
│ with aws_s3_bucket_acl.simple-web-app-logs,
│ on s3.tf line 3, in resource "aws_s3_bucket_acl" "simple-web-app-logs":
│ 3: resource "aws_s3_bucket_acl" "simple-web-app-logs" {
My s3.tf
resource "aws_s3_bucket_acl" "simple-web-app-logs" {
bucket = "kevindenotariis-simple-web-app-logs"
acl = "private"
}
# S3 Bucket storing jenkins user data
resource "aws_s3_bucket_acl" "jenkins-config" {
bucket = "kevindenotariis-jenkins-config"
acl = "private"
}
From jenkins.tf,two relevent lines
bucket-logs-name = aws_s3_bucket_acl.simple-web-app-logs.id
bucket-config-name = aws_s3_bucket_acl.jenkins-config.id
I tried Terraform plan
Terraform will perform the following actions:
# aws_s3_bucket_acl.jenkins-config will be created
+ resource "aws_s3_bucket_acl" "jenkins-config" {
+ acl = "private"
+ bucket = "kevindenotariis-jenkins-config"
+ id = (known after apply)
+ access_control_policy {
+ grant {
+ permission = (known after apply)
+ grantee {
+ display_name = (known after apply)
+ email_address = (known after apply)
+ id = (known after apply)
+ type = (known after apply)
+ uri = (known after apply)
}
}
+ owner {
+ display_name = (known after apply)
+ id = (known after apply)
}
}
}
# aws_s3_bucket_acl.simple-web-app-logs will be created
+ resource "aws_s3_bucket_acl" "simple-web-app-logs" {
+ acl = "private"
+ bucket = "kevindenotariis-simple-web-app-logs"
+ id = (known after apply)
+ access_control_policy {
+ grant {
+ permission = (known after apply)
+ grantee {
+ display_name = (known after apply)
+ email_address = (known after apply)
+ id = (known after apply)
+ type = (known after apply)
+ uri = (known after apply)
}
}
+ owner {
+ display_name = (known after apply)
+ id = (known after apply)
}
}
}
Plan: 2 to add, 0 to change, 0 to destroy.
How to fix this issue?
SOLVED
By removing
acl = "private"
line
I reread again the above link, Terraform AWS Provider Version 4 Upgrade Guide.

Terraform destroys the instance inside RDS cluster when upgrading

I have created a RDS cluster with 2 instances using terraform. When I am upgrading the RDS from front-end, it modifies the cluster. But when I do the same using terraform, it destroys the instance.
We tried create_before_destroy, and it gives error.
We tried with ignore_changes=engine but that didn't make any changes.
Is there any way to prevent it?
resource "aws_rds_cluster" "rds_mysql" {
cluster_identifier = var.cluster_identifier
engine = var.engine
engine_version = var.engine_version
engine_mode = var.engine_mode
availability_zones = var.availability_zones
database_name = var.database_name
port = var.db_port
master_username = var.master_username
master_password = var.master_password
backup_retention_period = var.backup_retention_period
preferred_backup_window = var.engine_mode == "serverless" ? null : var.preferred_backup_window
db_subnet_group_name = var.create_db_subnet_group == "true" ? aws_db_subnet_group.rds_subnet_group[0].id : var.db_subnet_group_name
vpc_security_group_ids = var.vpc_security_group_ids
db_cluster_parameter_group_name = var.create_cluster_parameter_group == "true" ? aws_rds_cluster_parameter_group.rds_cluster_parameter_group[0].id : var.cluster_parameter_group
skip_final_snapshot = var.skip_final_snapshot
deletion_protection = var.deletion_protection
allow_major_version_upgrade = var.allow_major_version_upgrade
lifecycle {
create_before_destroy = false
ignore_changes = [availability_zones]
}
}
resource "aws_rds_cluster_instance" "cluster_instances" {
count = var.engine_mode == "serverless" ? 0 : var.cluster_instance_count
identifier = "${var.cluster_identifier}-${count.index}"
cluster_identifier = aws_rds_cluster.rds_mysql.id
instance_class = var.instance_class
engine = var.engine
engine_version = aws_rds_cluster.rds_mysql.engine_version
db_subnet_group_name = var.create_db_subnet_group == "true" ? aws_db_subnet_group.rds_subnet_group[0].id : var.db_subnet_group_name
db_parameter_group_name = var.create_db_parameter_group == "true" ? aws_db_parameter_group.rds_instance_parameter_group[0].id : var.db_parameter_group
apply_immediately = var.apply_immediately
auto_minor_version_upgrade = var.auto_minor_version_upgrade
lifecycle {
create_before_destroy = false
ignore_changes = [engine_version]
}
}
Error:
resource \"aws_rds_cluster_instance\" \"cluster_instances\" {\n\n\n\nError: error creating RDS Cluster (aurora-cluster-mysql) Instance: DBInstanceAlreadyExists: DB instance already exists\n\tstatus code: 400, request id: c6a063cc-4ffd-4710-aff2-eb0667b0774f\n\n on
Plan output:
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
+/- create replacement and then destroy
Terraform will perform the following actions:
# module.rds_aurora_create[0].aws_rds_cluster.rds_mysql will be updated in-place
~ resource "aws_rds_cluster" "rds_mysql" {
~ allow_major_version_upgrade = false -> true
~ engine_version = "5.7.mysql_aurora.2.07.1" -> "5.7.mysql_aurora.2.08.1"
id = "aurora-cluster-mysql"
tags = {}
# (33 unchanged attributes hidden)
}
# module.rds_aurora_create[0].aws_rds_cluster_instance.cluster_instances[0] must be replaced
+/- resource "aws_rds_cluster_instance" "cluster_instances" {
~ arn = "arn:aws:rds:us-east-1:account:db:aurora-cluster-mysql-0" -> (known after apply)
~ availability_zone = "us-east-1a" -> (known after apply)
~ ca_cert_identifier = "rds-ca-" -> (known after apply)
~ dbi_resource_id = "db-32432432SDF" -> (known after apply)
~ endpoint = "aurora-cluster-mysql-0.jkjk.us-east-1.rds.amazonaws.com" -> (known after apply)
~ engine_version = "5.7.mysql_aurora.2.07.1" -> "5.7.mysql_aurora.2.08.1" # forces replacement
~ id = "aurora-cluster-mysql-0" -> (known after apply)
+ identifier_prefix = (known after apply)
+ kms_key_id = (known after apply)
+ monitoring_role_arn = (known after apply)
~ performance_insights_enabled = false -> (known after apply)
+ performance_insights_kms_key_id = (known after apply)
~ port = 3306 -> (known after apply)
~ preferred_backup_window = "07:00-09:00" -> (known after apply)
~ preferred_maintenance_window = "thu:06:12-thu:06:42" -> (known after apply)
~ storage_encrypted = false -> (known after apply)
- tags = {} -> null
~ tags_all = {} -> (known after apply)
~ writer = true -> (known after apply)
# (12 unchanged attributes hidden)
}
Plan: 1 to add, 1 to change, 1 to destroy.
I see apply_immediately argument not there in aws_rds_cluster resource , can you add that and try.
Terraform is seeing the engine version change on the instances and is detecting this as an action that forces replacement.
Remove (or ignore changes to) the engine_version input for the aws_rds_cluster_instance resources.
AWS RDS upgrades the engine version for cluster instances itself when you upgrade the engine version of the cluster (this is why you can do an in-place upgrade via the AWS console).
By excluding the engine_version input, Terraform will see no changes made to the aws_rds_cluster_instances and will do nothing.
AWS will handle the engine upgrades for the instances internally.
If you decide to ignore changes, use the ignore_changes argument within a lifecycle block:
resource "aws_rds_cluster_instance" "cluster_instance" {
engine_version = aws_rds_cluster.main.engine_version
...
lifecycle {
ignore_changes = [engine_version]
}
}
I didn't know that, but after some Googling I found this:
https://github.com/hashicorp/terraform-provider-aws/issues/10714
i.e. a bug report to AWS Terraform provider:
resource/aws_rds_cluster_instance is being destroyed and re-created when updating engine_version while apply_immediately is set to false
which seems to be the very same issue you are facing.
One comment there seems to point to a solution:
As of v3.63.0 (EDITED) of the provider, updates to the engine_version parameter of aws_rds_cluster_instance resources no longer forces replacement of the resource.
The original comment seems to have a typo - 3.36 vs. 3.63.
Can you try upgrading your aws Terraform provider?

Attempting to create a storage container for azurerm backend fails with 404 - The specified resource does not exist

I am trying to setup an azurerm backend using the following Terraform code:
modules\remote-state\main.tf
provider "azurerm" {
}
variable "env" {
type = string
description = "The SDLC environment (qa, dev, prod, etc...)"
}
locals {
extended_name = "dfpg-${lower(var.env)}-tfstate"
}
##################################################################################
# RESOURCES
##################################################################################
resource "azurerm_resource_group" "setup" {
name = "app505-${local.extended_name}-eastus2"
location = "eastus2"
}
resource "azurerm_storage_account" "sa" {
name = replace(local.extended_name, "-", "")
resource_group_name = azurerm_resource_group.setup.name
location = azurerm_resource_group.setup.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "ct" {
name = "terraform-state"
storage_account_name = azurerm_storage_account.sa.name
}
data "azurerm_storage_account_sas" "state" {
connection_string = azurerm_storage_account.sa.primary_connection_string
https_only = true
resource_types {
service = true
container = true
object = true
}
services {
blob = true
queue = false
table = false
file = false
}
start = timestamp()
expiry = timeadd(timestamp(), "17520h")
permissions {
read = true
write = true
delete = true
list = true
add = true
create = true
update = false
process = false
}
}
##################################################################################
# OUTPUT
##################################################################################
resource "null_resource" "post-config" {
depends_on = [azurerm_storage_container.ct]
provisioner "local-exec" {
command = <<EOT
Set-Content -Value 'storage_account_name = "${azurerm_storage_account.sa.name}"' -Path "backend-config.txt"
Add-Content -Value 'container_name = "terraform-state"' -Path "backend-config.txt"
Add-Content -Value 'key = "terraform.tfstate"' -Path "backend-config.txt"
Add-Content -Value 'sas_token = "${data.azurerm_storage_account_sas.state.sas}"' -Path "backend-config.txt"
EOT
interpreter = ["PowerShell", "-NoProfile", "-Command"]
}
}
qa\bootstrap\rs\main.tf
module "bootstrap" {
source = "../../../modules/remote-state"
env = "qa"
}
terraform init
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡]> terraform init
Initializing modules...
- bootstrap in ..\..\..\modules\remote-state
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 1.41.0...
- Downloading plugin for provider "null" (hashicorp/null) 2.1.2...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.azurerm: version = "~> 1.41"
* provider.null: version = "~> 2.1"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡]>
terraform plan -out main.tfplan
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡]> terraform plan -out main.tfplan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
# module.bootstrap.data.azurerm_storage_account_sas.state will be read during apply
# (config refers to values not yet known)
<= data "azurerm_storage_account_sas" "state" {
+ connection_string = (sensitive value)
+ expiry = (known after apply)
+ https_only = true
+ id = (known after apply)
+ sas = (sensitive value)
+ start = (known after apply)
+ permissions {
+ add = true
+ create = true
+ delete = true
+ list = true
+ process = false
+ read = true
+ update = false
+ write = true
}
+ resource_types {
+ container = true
+ object = true
+ service = true
}
+ services {
+ blob = true
+ file = false
+ queue = false
+ table = false
}
+ timeouts {
+ read = (known after apply)
}
}
# module.bootstrap.azurerm_resource_group.setup will be created
+ resource "azurerm_resource_group" "setup" {
+ id = (known after apply)
+ location = "eastus2"
+ name = "app505-dfpg-qa-tfstate-eastus2"
+ tags = (known after apply)
}
# module.bootstrap.azurerm_storage_account.sa will be created
+ resource "azurerm_storage_account" "sa" {
+ access_tier = (known after apply)
+ account_encryption_source = "Microsoft.Storage"
+ account_kind = "Storage"
+ account_replication_type = "LRS"
+ account_tier = "Standard"
+ account_type = (known after apply)
+ enable_advanced_threat_protection = (known after apply)
+ enable_blob_encryption = true
+ enable_file_encryption = true
+ id = (known after apply)
+ is_hns_enabled = false
+ location = "eastus2"
+ name = "dfpgqatfstate"
+ primary_access_key = (sensitive value)
+ primary_blob_connection_string = (sensitive value)
+ primary_blob_endpoint = (known after apply)
+ primary_blob_host = (known after apply)
+ primary_connection_string = (sensitive value)
+ primary_dfs_endpoint = (known after apply)
+ primary_dfs_host = (known after apply)
+ primary_file_endpoint = (known after apply)
+ primary_file_host = (known after apply)
+ primary_location = (known after apply)
+ primary_queue_endpoint = (known after apply)
+ primary_queue_host = (known after apply)
+ primary_table_endpoint = (known after apply)
+ primary_table_host = (known after apply)
+ primary_web_endpoint = (known after apply)
+ primary_web_host = (known after apply)
+ resource_group_name = "app505-dfpg-qa-tfstate-eastus2"
+ secondary_access_key = (sensitive value)
+ secondary_blob_connection_string = (sensitive value)
+ secondary_blob_endpoint = (known after apply)
+ secondary_blob_host = (known after apply)
+ secondary_connection_string = (sensitive value)
+ secondary_dfs_endpoint = (known after apply)
+ secondary_dfs_host = (known after apply)
+ secondary_file_endpoint = (known after apply)
+ secondary_file_host = (known after apply)
+ secondary_location = (known after apply)
+ secondary_queue_endpoint = (known after apply)
+ secondary_queue_host = (known after apply)
+ secondary_table_endpoint = (known after apply)
+ secondary_table_host = (known after apply)
+ secondary_web_endpoint = (known after apply)
+ secondary_web_host = (known after apply)
+ tags = (known after apply)
+ blob_properties {
+ delete_retention_policy {
+ days = (known after apply)
}
}
+ identity {
+ principal_id = (known after apply)
+ tenant_id = (known after apply)
+ type = (known after apply)
}
+ network_rules {
+ bypass = (known after apply)
+ default_action = (known after apply)
+ ip_rules = (known after apply)
+ virtual_network_subnet_ids = (known after apply)
}
+ queue_properties {
+ cors_rule {
+ allowed_headers = (known after apply)
+ allowed_methods = (known after apply)
+ allowed_origins = (known after apply)
+ exposed_headers = (known after apply)
+ max_age_in_seconds = (known after apply)
}
+ hour_metrics {
+ enabled = (known after apply)
+ include_apis = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
}
+ logging {
+ delete = (known after apply)
+ read = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
+ write = (known after apply)
}
+ minute_metrics {
+ enabled = (known after apply)
+ include_apis = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
}
}
}
# module.bootstrap.azurerm_storage_container.ct will be created
+ resource "azurerm_storage_container" "ct" {
+ container_access_type = "private"
+ has_immutability_policy = (known after apply)
+ has_legal_hold = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ name = "terraform-state"
+ properties = (known after apply)
+ resource_group_name = (known after apply)
+ storage_account_name = "dfpgqatfstate"
}
# module.bootstrap.null_resource.post-config will be created
+ resource "null_resource" "post-config" {
+ id = (known after apply)
}
Plan: 4 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
This plan was saved to: main.tfplan
To perform exactly these actions, run the following command to apply:
terraform apply "main.tfplan"
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡]>
So far so good. Now applying:
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡]> terraform.exe apply .\main.tfplan
module.bootstrap.azurerm_resource_group.setup: Creating...
module.bootstrap.azurerm_resource_group.setup: Creation complete after 3s [id=/subscriptions/*SUB-GUID*/resourceGroups/app505-dfpg-qa-tfstate-eastus2]
module.bootstrap.azurerm_storage_account.sa: Creating...
module.bootstrap.azurerm_storage_account.sa: Still creating... [10s elapsed]
module.bootstrap.azurerm_storage_account.sa: Still creating... [20s elapsed]
module.bootstrap.azurerm_storage_account.sa: Still creating... [30s elapsed]
module.bootstrap.azurerm_storage_account.sa: Creation complete after 32s [id=/subscriptions/*SUB-GUID*/resourceGroups/app505-dfpg-qa-tfstate-eastus2/providers/Microsoft.Storage/storageAccounts/dfpgqatfstate]
module.bootstrap.data.azurerm_storage_account_sas.state: Refreshing state...
module.bootstrap.azurerm_storage_container.ct: Creating...
Error: Error creating Container "terraform-state" (Account "dfpgqatfstate" / Resource Group "app505-dfpg-qa-tfstate-eastus2"): containers.Client#Create: Failure responding to request: StatusCode=404 -- Original Error: autorest/azure: Service returned an error. Status=404 Code="ResourceNotFound" Message="The specified resource does not exist.\nRequestId:4dcdd560-901e-005e-130d-d3a867000000\nTime:2020-01-24T23:26:53.6811230Z"
on ..\..\..\modules\remote-state\main.tf line 29, in resource "azurerm_storage_container" "ct":
29: resource "azurerm_storage_container" "ct" {
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡ +1 ~0 -0 !]>
Now running the second time works:
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡ +1 ~0 -0 !]> terraform.exe apply .\main.tfplan
module.bootstrap.azurerm_resource_group.setup: Creating...
module.bootstrap.azurerm_resource_group.setup: Creation complete after 2s [id=/subscriptions/*SUB-GUID*/resourceGroups/app505-dfpg-qa-tfstate-eastus2]
module.bootstrap.azurerm_storage_account.sa: Creating...
module.bootstrap.azurerm_storage_account.sa: Creation complete after 7s [id=/subscriptions/*SUB-GUID*/resourceGroups/app505-dfpg-qa-tfstate-eastus2/providers/Microsoft.Storage/storageAccounts/dfpgqatfstate]
module.bootstrap.data.azurerm_storage_account_sas.state: Refreshing state...
module.bootstrap.azurerm_storage_container.ct: Creating...
module.bootstrap.azurerm_storage_container.ct: Creation complete after 1s [id=https://dfpgqatfstate.blob.core.windows.net/terraform-state]
module.bootstrap.null_resource.post-config: Creating...
module.bootstrap.null_resource.post-config: Provisioning with 'local-exec'...
module.bootstrap.null_resource.post-config (local-exec): Executing: ["PowerShell" "-NoProfile" "-Command" "Set-Content -Value 'storage_account_name = \"dfpgqatfstate\"' -Path \"backend-config.txt\"\r\nAdd-Content -Value 'container_name = \"terraform-state\"' -Path \"backend-config.txt\"\r\nAdd-Content -Value 'key = \"terraform.tfstate\"' -Path \"backend-config.txt\"\r\nAdd-Content -Value 'sas_token = \"?sv=2017-07-29&ss=b&srt=sco&sp=rwdlac&se=2022-01-23T23:29:47Z&st=2020-01-24T23:29:47Z&spr=https&sig=***\"' -Path \"backend-config.txt\"\r\n"]
module.bootstrap.null_resource.post-config: Creation complete after 1s [id=5713483326668430483]
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.
State path: terraform.tfstate
C:\xyz\terraform\qa\bootstrap\rs [shelve/terraform ≡ +2 ~0 -0 !]>
But why do I have to run it twice? What am I doing wrong?
Edit 1
I tried it several times on my laptop (destroying in the middle, of course) and it consistently failed. Then I activated trace log and 5 minutes later it passed for the first time. No idea why it took it 5 minutes. The network seems to be just fine on my end.
My laptop is on a VPN to work. I will now try from the workstation at work without VPN.
Edit 2
Tried on the workstation in the office. First time succeeded, but suspicious as I am, I destroyed and retried and it failed the second time.
Edit 3
We have ZScaler installed.

Resources