Я пытаюсь настроить сервер Azurerm, используя следующий код Terraform:
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 ≡]>
Пока все хорошо. Теперь применяем:
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 !]>
Теперь работает второй раз:
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 !]>
Но почему я должен запустить его дважды? Что я делаю не так?
Edit 1
Я пробовал несколько раз на своем ноутбуке (конечно, в середине), и он постоянно терпел неудачу. Затем я активировал журнал трассировки и через 5 минут он прошел впервые. Понятия не имею, почему это заняло 5 минут. Сеть, кажется, просто отлично с моей стороны.
Мой ноутбук работает по VPN. Сейчас попробую с рабочей станции на работе без VPN.
Редактировать 2
Пробовал на рабочей станции в офисе. Первый раз удался, но, как ни странно, я уничтожил и повторил попытку, и во второй раз это не удалось.
Edit 3
У нас установлен ZScaler.