Terraform Problem to define cyrilgdn/postgresql provider properly - terraform

I have the exact same problem as here Terraform tries to load old defunct provider and the solution posted there does not work for me.
Problem is that i define in the terraform config:
required_providers {
postgresql = {
source = "cyrilgdn/postgresql"
version = ">=1.13.0"
}
}
But the terraform init process always tries to download hashicorp/postgresql and can not find it in the end.
My current terraform version is:
Terraform v1.0.6 on windows_amd64
I did try a lot and played around with the resource parameter "provider" to explicitly set the provider for all resources but even with that i did not find a way.
Can anybody help here again or post me a working example for this provider?

I got the solution! The problem what i had was my folder structure. I had a specific folder structure like:
environments like dev/int/prod and i had a config.tf in there with the required providers.
resources where i use the resources i want to add and what i missed there is the a copy of the config.tf file.
So this means i need a config.tf file in every subfolder which consists modules.

Related

Error: Provider configuration not present

Im trying to update terraform version from 0.12 to 0.13. While updating the terraform I came across on an issue during plan
Error: Provider configuration not present
To work with
aws_sns_topic_subscription.sns_s3_raw_parquet_sqs_user_cleansing_monet_service_subscription
its original provider configuration at provider["registry.terraform.io/-/aws"]
is required, but it has been removed. This occurs when a provider
configuration is removed while objects created by that provider still exist in
the state. Re-add the provider configuration to destroy
aws_sns_topic_subscription.sns_s3_raw_parquet_sqs_user_cleansing_monet_service_subscription,
after which you can remove the provider configuration again.
Could someone please help?
Most likely you have not proceeded with the migration to Terraform v.013 fully.
Make a backup of your current state with terraform state pull then try to execute the following:
terraform state replace-provider 'registry.terraform.io/-/aws' 'registry.terraform.io/hashicorp/aws'
This should amend your state to the newer Terraform version.
Most of the time you'll have a global.tf file in your directory that lists some things that might not actually be resources. This is where you'd normally have a block like this:
provider "aws" {
region = "REGION"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
Looks like that block, whatever file it was in, got deleted. Add it back and then try again. Note you'll need to change REGION to whatever region you put your resources in. In lieu of access_key and secret_key, some people use a profile and put it in ~/.aws/credentials.

terraform interpolation with variables returning error [duplicate]

# Using a single workspace:
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "company"
workspaces {
name = "my-app-prod"
}
}
}
For Terraform remote backend, would there be a way to use variable to specify the organization / workspace name instead of the hardcoded values there?
The Terraform documentation
didn't seem to mention anything related either.
The backend configuration documentation goes into this in some detail. The main point to note is this:
Only one backend may be specified and the configuration may not contain interpolations. Terraform will validate this.
If you want to make this easily configurable then you can use partial configuration for the static parts (eg the type of backend such as S3) and then provide config at run time interactively, via environment variables or via command line flags.
I personally wrap Terraform actions in a small shell script that runs terraform init with command line flags that uses an appropriate S3 bucket (eg a different one for each project and AWS account) and makes sure the state file location matches the path to the directory I am working on.
I had the same problems and was very disappointed with the need of additional init/wrapper scripts. Some time ago I started to use Terragrunt.
It's worth taking a look at Terragrunt because it closes the gap between Terraform and the lack of using variables at some points, e.g. for the remote backend configuration:
https://terragrunt.gruntwork.io/docs/getting-started/quick-start/#keep-your-backend-configuration-dry

Use variable in Terraform remote backend

# Using a single workspace:
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "company"
workspaces {
name = "my-app-prod"
}
}
}
For Terraform remote backend, would there be a way to use variable to specify the organization / workspace name instead of the hardcoded values there?
The Terraform documentation
didn't seem to mention anything related either.
The backend configuration documentation goes into this in some detail. The main point to note is this:
Only one backend may be specified and the configuration may not contain interpolations. Terraform will validate this.
If you want to make this easily configurable then you can use partial configuration for the static parts (eg the type of backend such as S3) and then provide config at run time interactively, via environment variables or via command line flags.
I personally wrap Terraform actions in a small shell script that runs terraform init with command line flags that uses an appropriate S3 bucket (eg a different one for each project and AWS account) and makes sure the state file location matches the path to the directory I am working on.
I had the same problems and was very disappointed with the need of additional init/wrapper scripts. Some time ago I started to use Terragrunt.
It's worth taking a look at Terragrunt because it closes the gap between Terraform and the lack of using variables at some points, e.g. for the remote backend configuration:
https://terragrunt.gruntwork.io/docs/getting-started/quick-start/#keep-your-backend-configuration-dry

understand the terraform for OCI

I have 3 questions here:
I have created terraform form scripts in Oracle Cloud Infrastructure to build the instance and other resources. But I am not able to get any script for route table configuration and service in network script. So i have made them manual. my current table has only the resource name, rest all configuration is blank. So i need help in getting a properly supported script for OCI to create route table with configuration.
As i did such things manually, i am not able to give terraform apply after doing some changes in the script, as terraform apply will delete all the rules which i created manually. So is it mandatory to give terraform apply every time when i change the script? or can i enter the config manually and simultaneously match that in the terraform script so that everything is intact?
After every terraform changes i could see 2 files is getting enlarge (terraform.tfstate, terraform.tfstate.backup) what are these two files? if that is a backup file, then how will it help me to restore if i mess up in my configuration?
In Terraform, the configuration script is always the source of truth. When you apply a configuration; Terraform will favor the settings of that configuration and override any changes that were manually done outside of Terraform.
To make sure your manual changes are not overwritten, you should make sure the configuration always matches the manual changes. One way to import manual resources into your configuration is using "terraform import" (see https://www.terraform.io/docs/import/index.html).
The terraform.tfstate and terraform.tfstate.backup files are used by Terraform to keep track of the latest state of the resources that Terraform has created. These files are used to help Terraform determine whether you configuration script has drifted from the state; so it knows how to apply your configuration script. To my knowledge, these state files are not intended to be backup files if you mess up your configuration. (see https://www.terraform.io/docs/state/index.html)
Hope this helps.
Here is an example for a route table resource in Terraform config file:
resource "oci_core_route_table" "webserver-rt" {
compartment_id = "${var.compartment_ocid}"
vcn_id = "${oci_core_virtual_network.oci-vcn.id}"
display_name = "webserver-rt"
route_rules = [{
destination = "0.0.0.0/0"
network_entity_id = "${oci_core_internet_gateway.internet-gateway.id}"
}]
}
You may find more details here: https://github.com/terraform-providers/terraform-provider-oci/blob/master/docs/examples/networking/route_table/route_table.tf

How to use multiple Terraform Providers sequentially

How can I get Terraform 0.10.1 to support two different providers without having to run 'terraform init' every time for each provider?
I am trying to use Terraform to
1) Provision an API server with the 'DigitalOcean' provider
2) Subsequently use the 'Docker' provider to spin up my containers
Any suggestions? Do I need to write an orchestrating script that wraps Terraform?
Terraform's current design struggles with creating "multi-layer" architectures in a single configuration, due to the need to pass dynamic settings from one provider to another:
resource "digitalocean_droplet" "example" {
# (settings for a machine running docker)
}
provider "docker" {
host = "tcp://${digitalocean_droplet.example.ipv4_address_private}:2376/"
}
As you saw in the documentation, passing dynamic values into provider configuration doesn't fully work. It does actually partially work if you use it with care, so one way to get this done is to use a config like the above and then solve the "chicken-and-egg" problem by forcing Terraform to create the droplet first:
$ terraform plan -out=tfplan -target=digitalocean_droplet.example
The above will create a plan that only deals with the droplet and any of its dependencies, ignoring the docker resources. Once the Docker droplet is up and running, you can then re-run Terraform as normal to complete the setup, which should then work as expected because the Droplet's ipv4_address_private attribute will then be known. As long as the droplet is never replaced, Terraform can be used as normal after this.
Using -target is fiddly, and so the current recommendation is to split such systems up into multiple configurations, with one for each conceptual "layer". This does, however, require initializing two separate working directories, which you indicated in your question that you didn't want to do. This -target trick allows you to get it done within a single configuration, at the expense of an unconventional workflow to get it initially bootstrapped.
Maybe you can use a provider instance within your resources/module to set up various resources with various providers.
https://www.terraform.io/docs/configuration/providers.html#multiple-provider-instances
The doc talks about multiple instances of same provider but I believe the same should be doable with distinct providers as well.
A little bit late...
Well, got the same Problem. My workaround is to create modules.
First you need a module for your docker Provider with an ip variable:
# File: ./docker/main.tf
variable "ip" {}
provider "docker" {
host = "tcp://${var.ip}:2375/"
}
resource "docker_container" "www" {
provider = "docker"
name = "www"
}
Next one is to load that modul in your root configuration:
# File: .main.tf
module "docker01" {
source = "./docker"
ip = "192.169.10.12"
}
module "docker02" {
source = "./docker"
ip = "192.169.10.12"
}
True, you will create on every node the same container, but in my case that's what i wanted. I currently haven't found a way to configure the hosts with an individual configuration. Maybe nested modules, but that didn't work in the first tries.

Resources