Lock file error when importing resource in terraform - azure

I'm trying to import 2 existing azure resources (1 vnet and 1 resource group).
If I add the following to my main.tf
resource "azurerm_virtual_network" "my-vnet" {
}
and run terraform import azurerm_virtual_network.my-vnet /subscriptions/11111111/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet-01
Everything works perfectly, the terraform.tfstate file gets updated with the vnet information etc.
If I then add the following to the main.tf
resource "azurem_resource_group" "my-net-rsg" {
}
and run terraform import azurem_resource_group.my-net-rsg /subscriptions/11111111/resourceGroups/my-net-rsg
I get the following error
If I then remove
resource "azurem_resource_group" "my-net-rsg" {
}
and run the same terraform import azurem_resource_group.my-net-rsg /subscriptions/11111111/resourceGroups/my-net-rsg I get an error (quite rightly & expectedly) saying
Before importing this resource, please create its configuration in the root module. For example:
resource "azurem_resource_group" "my-net-rsg" {
# (resource arguments)
}
Even if I literally copy and paste that output back into my main.tf file I get the same error from the screen shot above.
I've tried only having the resource group config
I've tried having the resource config first before the vnet
I've tried a fresh terraform init in a different directory and walking through the process again.
Every time if I have the resource group in the main.tf it complains about the lock file.

I was just going to delete the question as it is such a simple problem/solution, but because the error is so non-descript as to the cause this might be helpful to someone
Apparently
Is terraform for you have a typo in your resource name.
resource "azurem_resource_group" should be (in this case) resource "azurerm_resource_group"

Related

shares.Client#GetProperties: Failure sending request: StatusCode=0 -- Original Error: context deadline exceeded

I've deployed a new file share on a storage account I have in Azure and ever since I did that I am no longer able to perform terraform plan and instead getting the following error:
azurerm_storage_account_customer_managed_key.this[0]: Refreshing state... [id=/subscriptions/**********/resourceGroups/myrg/providers/Microsoft.Storage/storageAccounts/myaccount]
╷
│ Error: shares.Client#GetProperties: Failure sending request: StatusCode=0 -- Original Error: context deadline exceeded
│
│ with azurerm_storage_share.this["share1"],
│ on main.tf line 155, in resource "azurerm_storage_share" "this":
│ 155: resource "azurerm_storage_share" "this" {
│
╵
Destroy False detailedExitCode: 1
Error detected by Terraform
##[error]Script failed with exit code: 1
I've tried setting the storage account networking to public (Enable from all networks) and still the same.
I've tried different Terraform versions (1.2.6, 1.0.4, 1.2.7, 1.2.0) - same outcome.
I've looked it up online and came up with these two tickets that seem similar but have yet to receive an answer (though they are not from Stack Overflow):
https://github.com/hashicorp/terraform-provider-azurerm/issues/17851
https://github.com/hashicorp/terraform-provider-azurerm/issues/2977
I have run out of leads to investigate at the moment , and I'd appreciate if someone might have new ideas as to what's causing the issue.
Let me know if I can share more information.
In my case i got the similar kind of error when i have not cleared the state
file (TF) in which other resource is present which is not present in
azure portal.(As I have manually deleted it in the portal but still
present in the terraform state file.)
I erased the resources which are not present in the azure portal and then tried to execute the same.
Or If some sources are present in azure and not in terraform state file.In this case
make sure to import the resources using terraform import <terraformid> <resourceId> something like this azurerm_resource_group | Resources | registry.terraform.io or this SO ref by checking the mismatch in resources in azure portal and terraform.tfstate file.
For example Resource Groups can be imported as:
terraform import azurerm_resource_group.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example
After making sure the state file matches the resources present in
portal, then try and execute.
I tried in my environment and able to execute terraform plan and terraform apply
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "xxxxxxx"
location = "westus2"
}
resource "azurerm_storage_account" "test" {
name = "acctestacc1234"
resource_group_name = azurerm_resource_group.example.name
location = "westus2"
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_share" "test" {
name = "testkaaccount"
storage_account_name = azurerm_storage_account.test.name
quota = 5
access_tier = "TransactionOptimized"
}
Result:
Also please check with the location if it correctly given refering to
resource group location and if it is created in VM ,make sure the vm
and the resources created are in the same location .
References:
azurerm_storage_share_file | Resources | hashicorp/azurerm |
Terraform Registry
Terraform Azure Configure VM Backup Policy Fails - Stack Overflow
So Terraform uses private urls for management of the file share. In our cases DNS resolving of these endpoints was not working correctly. You can get the URL for the private endpoint using the command terraform console and then investigate the resource >azurerm_storage_share.file_share . It will show the private URL. Subsequently, use the nslookup or dig command to determine if you can resolve the URL to an IP address. If you are not able to resolve the URL there are several options. For example you could add them to your /etc/hosts file. This solved it our case. Another option is to add the private link to a private DNS zone and forward you local DNS to this private zone.

Diagnostic Settings - Master" already exists - to be managed via Terraform this resource needs to be imported into the State

I have a diagnostic setting configured on my master db. As shown below in my main.tf
resource "azurerm_monitor_diagnostic_setting" "main" {
name = "Diagnostic Settings - Master"
target_resource_id = "${azurerm_mssql_server.main.id}/databases/master"
log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id
log {
category = "SQLSecurityAuditEvents"
enabled = true
retention_policy {
enabled = false
}
}
metric {
category = "AllMetrics"
retention_policy {
enabled = false
}
}
lifecycle {
ignore_changes = [log, metric]
}
}
If I don't delete it before in the resource group before I run the Terraform, I get the error:
Diagnostic Settings - Master" already exists - to be managed via
Terraform this resource needs to be imported into the State
I know that if I delete the SQL Server the diagnostic setting remains - but I don't know why that is a problem with Terraform. I have also noticed that it is in my tfplan.
What could be the problem?
If I don't delete it before in the resource group before I run the
Terraform, I get the error:
Diagnostic Settings - Master" already exists - to be managed via Terraform this resource needs to be imported into the State
I know that if I delete the SQL Server the diagnostic setting remains but I don't know why that is a problem with Terraform.
If you have created the resource in Azure from a different way (i.e. Portal/Templates/CLI/Powershell), that means Terraform is not aware of resource already existing in Azure. So, during Terraform Plan, it shows you the plan what will be created from what you have written in main.tf. But when you run Terraform Apply the azurerm provider checks the resources names with the existing resources of the same resource providers and result in giving an error that it already exists and needs to be imported to be managed by Terraform.
Also if you have created everything from Terraform then doing a Terraform destroy deletes all the resources present on the main.tf.
Well, it's in the .tfplan and also it's in main.tf - so it's imported, right ?
If you mention the resource and its details in main.tf and .tfplan, it doesn't mean that you have imported the resource or Terraform gets aware of the resource. Terraform is only aware of the resources that are stored in the Terraform state file i.e. .tfstate.
So , to overcome the error that you get without deleting the resource from Portal, you will have to add the resource in the main.tf as you have already done and then use Terraform import command to import the Azure resource to Terraform State file like below:
terraform import azurerm_monitor_diagnostic_setting.example "{resourceID}|{DiagnosticsSettingsName}"
So, for you it will be like:
terraform import azurerm_monitor_diagnostic_setting.main "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Sql/servers/<SQLServerName>/databases/master|Diagnostic Settings - Master"
After the Import is done, any changes you make from Terraform to that resource will get reflected in portal as well and you will be able to destroy the resource from terraform as well.

How to automatically import resource to Terraform state?

I want to develop a single Terraform module to deploy my resources, with the resources being stored in separate YAML files. For example:
# resource_group_a.yml
name: "ResourceGroupA"
location: "westus"
# resource_group_b.yml
name: "ResourceGroupB"
location: "norwayeast"
And the following Terraform module:
# deploy/main.tf
variable source_file {
type = string # Path to a YAML file
}
locals {
rg = yamldecode(file(var.source_file))
}
resource "azurerm_resource_group" "rg" {
name = local.rg.name
location = local.rg.location
}
I can deploy the resource groups with:
terraform apply -var="source_file=resource_group_a.yml"
terraform apply -var="source_file=resource_group_b.yml"
But then I run into 2 problems, due to the state that Terraform keeps about my infrastructure:
If I deploy Resource Group A, it deletes Resource Group B and vice-versa.
If I manually remove the .tfstate file prior to running apply, and the resource group already exists, I get an error:
A resource with the ID "/..." already exists - to be managed via Terraform
this resource needs to be imported into the State.
with azurerm_resource_group.rg,
on main.tf line 8 in resource "azurerm_resource_group" "rg"
I can import the resource into my state with
terraform import azurerm_resource_group.reg "/..."
But it's a long file and there may be multiple resources that I need to import.
So my questions are:
How to keep the state separate between the two resource groups?
How to automatically import existing resources when I run terraform apply?
How to keep the state separate between the two resource groups?
I recommend using Terraform Workspaces for this, which will give you separate state files, each with an associated workspace name.
How to automatically import existing resources when I run terraform
apply?
That's not currently possible. There are some third-party tools out there like Terraformer for accomplishing automated imports, but in my experience they don't work very well, or they never support all the resource types you need. Even then they wouldn't import resources automatically every time you run terraform apply.

Error when creating Azure resources with Terraform

I'm trying to create Azure resources from Azure web site CLI, but strangely it throws the error below after run "terraform apply". It wasn't like this before.
Error: A resource with the ID "/subscriptions/certdab-as441-4a670-bsda-2456437/resourceGroups/commapi" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_resource_group" for more information.
on terra.tf line 14, in resource "azurerm_resource_group" "rg1":
14: resource "azurerm_resource_group" "rg1" {
Terraform code is below;
provider "azurerm" {
version = "=2.20.0"
features {}
subscription_id = "c413asdasdasdadsasda1c77"
tenant_id = "da956asdasdadsadsasd25a535"
}
resource "azurerm_resource_group" "rg" {
name = "commapi"
location = "West Europe"
}
resource "azurerm_resource_group" "rg1" {
name = "commapi"
location = "West Europe"
}
Regarding to their web site, if a resource group is alredy created, we should import it. But I don't get it how?
They said I should import like below, should I add this line to my terraform code?
Or should I run this import command for every Azure tool?
terraform import azurerm_resource_group.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1
So for example if I already created 10 Azure resources before and if I add 11.th tool to my Terraform code, should I run this "import" command for each that 10 resources which already created before? That's so weird.
How can I create these resources?
Edit:
If I try again, throws the error below;
Error: A resource with the ID "/subscriptions/asdd-asde1-4asd-bsda-asasd/resourceGroups/commerceapi/providers
/Microsoft.ApiManagement/service/commapi-apim" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_api_management" for more information.
on terra.tf line 65, in resource "azurerm_api_management" "apm":
65: resource "azurerm_api_management" "apm" {
Thanks!
Sample 2 :
For example when I create the API, it throws the error below;
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
azurerm_api_management.apm: Creating...
Error: A resource with the ID "/subscriptions/c4112313-123-123-123-1c77/resourceGroups/testapi/providers/Microsoft.ApiManagement/service/api-apim" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_api_management" for more information.
on commerceApi.tf line 67, in resource "azurerm_api_management" "apm":
67: resource "azurerm_api_management" "apm" {
After that, when I try to import command, this time it throws the error below;
PS C:\Users\set\Desktop\Terraform\Test_Commerceapi> terraform import azurerm_api_management.apm /subscriptions/c4asdb-234e1-23-234a-23424337/resourceGroups/testapi
azurerm_api_management.apm: Importing from ID "/subscriptions/c4234324-234-234-23-4347/resourceGroups/testapi"...
azurerm_api_management.apm: Import prepared!
Prepared azurerm_api_management for import
azurerm_api_management.apm: Refreshing state... [id=/subscriptions/c4234324-23-4234-234324-77/resourceGroups/testapi]
Error: making Read request on API Management Service "" (Resource Group "testapi"): apimanagement.ServiceClient#Get: Invalid input: autorest/validation: validation failed: parameter=serviceName constraint=MinLength value="" details: value length must be greater than or equal to 1
If you want to bring existing infrastructure under Terraform management, you can use Import.
For example, import an existing resource group.
declare the resource in the .tf file like this.
resource "azurerm_resource_group" "rg" {
}
Then run terraform import azurerm_resource_group.rg /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1 to import the existing resource group.
Then you can edit the Terraform file and add the name and location of the existing resource to the Resource Group. After this, you are ready to use the resource. Read how to Import an Existing Azure Resource in Terraform for more details.
Please note that Terraform import can only import resources into the state. It does not generate configuration. If you just intend to create new resources relying on existing resources, you could use data sources.
Data sources allow data to be fetched or computed for use elsewhere in
Terraform configuration. Use of data sources allows a Terraform
configuration to make use of information defined outside of Terraform,
or defined by another separate Terraform configuration.
For example, use Data Source: azurerm_resource_group to access information about an existing Resource Group. You can create new resources within the existing VNet.
data "azurerm_resource_group" "example" {
name = "existing"
}
output "id" {
value = data.azurerm_resource_group.example.id
}

Importing Existing Azure Storage Account Into Terraform Resource

I'm new to Terraform, and I'm trying to import two different existing Azure Storage Accounts into two "azurerm_storage_account" modules I'm creating in Terraform, "my_storage_account" and "my_storage_account_2".
I followed the Terraform import documentation and ran:
terraform import azurerm_storage_account.my_storage_account /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.Storage/storageAccounts/myaccount
...but got the following error message:
Error: resource address "azurerm_storage_account.my_storage_account" does not exist in the configuration.
Before importing this resource, please create its configuration in the root module. For example:
resource "azurerm_storage_account" "my_storage_account" {
# (resource arguments)
}
Inside the root module, I have:
resource "azurerm_storage_account" "storage_account" {
# (resource arguments)
}
It sounds like the error message is telling me to write "storage_account" instead of "my_storage_account", but how can I then import to a specific module of that resource?
You have this resource declared:
resource "azurerm_storage_account" "storage_account" {
# (resource arguments)
}
This resource is tracked internally by terrafrom with the id azurerm_storage_account.storage_account.
If you want to import a storage account and tell terraform that you mean exactly this resource, you have to use the id terraform uses internally. You can probably now see the differences in the following lines:
terraform import azurerm_storage_account.my_storage_account /subcriptions/...
terraform import azurerm_storage_account.storage_account /subcriptions/...
If you want to have multiple storage accounts managed by terraform, each of them will need to have its own unique resource stanza.
See also: https://www.terraform.io/docs/import/usage.html

Resources