Terraform - Use Gitlab provider to save secrets - gitlab

According to the documentation, there is already a Gitlab provider in Terraform. However, I can't find a way to create/update secrets in a project. Is that possible? Is there a related upcoming feature?
This would really help us in our work, as many output variables of terraform are required to configure other CI deployments we have.
We are using AWS, and some output variables like IAM credentials or subnet IDs cannot be assumed or deduced easily and at the moment we are struggling to find a way to forward them to our other tools.
Being able to do something like:
provider "gitlab" {
token = "${var.gitlab_token}"
url = "${var.gitlab_url}"
}
# Add a project secret
resource "gitlab_project_secret" "my_project_secret" {
project_name = "my_project"
secret_key = "${env}_AWS_SECRET_ACCESS_KEY"
secret_value = ""${module.my_iam_user_module.secret_access_key}"
}
Would save us a lot of pain.

It can't be done just yet although there is an open issue for it with a comment saying that someone was planning to start working on it a few months ago.
The Gitlab provider uses the upstream xanzy/go-gitlab project which does have support for project variables so it shouldn't be too much work to add it. If you are at all comfortable writing Go and/or have contributed to a Terraform provider before then it might be worth picking it up yourself considering the lack of updates on that issue.

Related

Deploying and configuring Postgres server in Azure with Terraform

I'm deploying Azure Postgres Flexible Server with Terraform as described in GitHub. The configuration works as expected, no issues there. The only divination from that GitHub template is that I want to configure pgBouncer for Postgres which is now supported natively. I don't see a way how I can create this configuration (i.e., enable this feature).
I've done some research and discovered the configuration feature is not quite available (at least according to the open ticket in GitHub here). At the same time, one of the published replies suggests using azurerm_postgresql_flexible_server_configuration and this resource type is available in Terraform indeed. However, Microsoft documentation states that to enable and configure pgBouncer I need to introduce 7 parameters. I thought that to make the code tidier, I can use a list and foreach loop, like this:
locals {
pg_config = {
"pgbouncer.default_pool_size" : "50",
"pgBouncer.max_client_conn" : "5000",
"pgBouncer.pool_mode" : "TRANSACTION"
etc...
}
}
resource "azurerm_postgresql_flexible_server_configuration" "postgres_fs_config" {
for_each = local.pg_config
name = each.key
value = each.value
server_id = azurerm_postgresql_flexible_server.postgres-fs.id
}
Is this the best way to configure Postgres (without involving CDK)? Did I miss something?
Ok, I verified this approach and it works like a charm. Will stick to it for now.

Terraform - Azure - Extract API from one resource group and import into another resource group

I have 5 different APIs in my Dev environment. This environment was built manually.
However, for the subsequent environments like Test, Pre-Prod, etc.. Terraform is being used.
Since I need to create each of the APIs in the subsequent environments, am extracting each of these APIs as a JSON file, making minor tweaks to the API URLs and importing it into the new environments.
The following is the process that am doing right now.
Went to Resource groups in Azure
Then under API Management service > APIs, clicked on the necessary API
Now, clicked on the three dots next to the API that I need and clicked on Export
Selected OpenAPI v3 (JSON) format
Now, I'm using the extracted JSON file and using the Terraform code below to add it to the APIM
resource "azurerm_api_management_api" "example" {
name = "example-api"
resource_group_name = azurerm_resource_group.example.name
api_management_name = azurerm_api_management.example.name
revision = "1"
display_name = "Example API"
path = "api/path"
protocols = ["https"]
service_url = "https://actualURL-of-the-API"
import {
content_format = "openapi+json"
content_value = file("extracted-filename.json")
}
}
The issue here is:
Even though the API gets added to the APIM, this doesn't create all the data - like Webservice URL, Backend HTTP(s) endpoint
How do I go about doing this?
Are you locked into exporting the Json file and importing it on the other environments through Terraform?
The reason I ask is because I attempted something similar but decided to go another route.
Initially I created the API manually in a Dev environment. I then re-created the same API from the ground up using only Terraform. No Json export & import.
I then used that Terraform script to create my other environments.
That allowed me to bypass the import problem altogether since nothing is imported.
I have found that there are downsides to taking this approach; It is much less intuitive to author the API through the Terraform script than through the Azure GUI. This is therefore more time consuming. Especially since my initial API was discarded for the one generated with the Terraform script.
Additionally, I have had problems with Terraform diffs reporting example changes when there are none (I suspect the same problem is to be had when using the import method).
If you are wondering why I decided to go another route? The reason was twofold; Firstly, similar to you, I had trouble with getting the export/import to generate the API that I wanted. Secondly, I prefer not to rely on auto generated files.

Terraform Problem to define cyrilgdn/postgresql provider properly

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.

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

Resources