terraform helm_release resource for official airflow helm chart - terraform

I was trying to deploy official helm chart for airflow using terraform helm release. But it says the chart repository not found. i put the repository url. May be the url is wrong.
repository = "https://airflow.apache.org"
chart = "apache-airflow"
name = "airflow"
version = "1.7.0"
namespace = "airflow"
values = [file("${path.module}/values.yaml")]
}
Getting this error message:
Error: could not download chart: chart "apache-airflow" version "1.7.0" not found in https://airflow.apache.org repository

I figured it out. As per instructions from the artifacthub.io [1], the chart name is actually only airflow (and not apache-airflow), so the code needs to look like:
resource "helm_release" "airflow" {
repository = "https://airflow.apache.org"
chart = "airflow"
name = "airflow"
version = "1.7.0"
namespace = "airflow"
values = [file("${path.root}/airflow-values.yaml")]
}
where the file aiflow-values.yaml is the one from their documentation used when installing with terraform [2].
[1] https://artifacthub.io/packages/helm/apache-airflow/airflow?modal=install
[2] https://airflow.apache.org/docs/helm-chart/stable/index.html#installing-the-chart-with-argo-cd-flux-or-terraform

Related

Why declaring different modules downloads as many registry modules locally , plus Error: Duplicate required providers configuration?

Just tried to create say 2 sets of resources using the same registry module which contains Oracle cloud compartments (multi level).
see Module link
I needed 2 subcompartments because set #2 is a child of set #1
example :
Terraform v1.0.3
module "main_compartment" {
source = "oracle-terraform-modules/iam/oci//modules/iam-compartment"
tenancy_ocid = var.tenancy_ocid
compartment_id = var.tenancy_ocid # define the parent compartment. Creation at tenancy root if omitted
compartment_name = "mycomp"
compartment_description = "main compartment at root level"
compartment_create = true
enable_delete = true
}
}
module "level_1_sub_compartments" {
source = "oracle-terraform-modules/iam/oci//modules/iam-compartment"
for_each = local.compartments.l1_subcomp
compartment_id = module.iam_compartment_main_compartment.compartment_id # define the parent compartment. Here we make reference to the previous module
compartment_name = each.value.compartment_name
compartment_description = each.value.description
compartment_create = true # if false, a data source with a matching name is created instead
enable_delete = true # if false, on `terraform destroy`, compartment is deleted from the terraform state but not from oci
}
...}
module "level_2_sub_compartments" {
source = "oracle-terraform-modules/iam/oci//modules/iam-compartment"
for_each = local.compartments.l2_subcomp
compartment_id = data.oci_identity_compartments.compx.id # define the parent compartment. Here we make reference to one of the l1 subcomp created in the previous module
compartment_name = each.value.compartment_name
compartment_description = each.value.description
compartment_create = true # if false, a data source with a matching name is created instead
enable_delete = true # if false, on `terraform destroy`, compartment is deleted from the terraform state but not from oci
depends_on = [module.level_1_sub_compartments,]
....}
When I run a terraform init I get as many folders than module blocks ? why would I call them this way?
Why not download a single module manually and then reference it 3 times as local modules .
Or better off writing dynamic blocks in the main.tf using regular compartment resource ?
Initializing modules...
Downloading oracle-terraform-modules/iam/oci 2.0.2 for iam_compartment_main...
. main_compartment in .terraform/modules/main_compartment/modules/iam-compartment
Downloading oracle-terraform-modules/iam/oci 2.0.2 for level_1_sub_compartments...
. level_1_sub_compartments in .terraform/modules/level_1_sub_compartments/modules/iam-compartment
Downloading oracle-terraform-modules/iam/oci 2.0.2 for level_2_sub_compartments...
. level_2_sub_compartments in .terraform/modules/level_2_sub_compartments/modules/iam-compartment
There are some problems with the configuration, described below.
...(for each module)=> Error: Duplicate required providers configuration
A module may have only one required providers configuration. The required providers were previously configured at .terraform/modules/level_1_sub_compartments/modules/iam-compartment/main.tf:5,3-21.
What I wanted is to reuse one registry module through URL source but only have one physical folder in my working directory.
I just expected it to work but it seems local Modules are the only working option for this goal.If there is anything I'm doing wrong please let me know as the provider error is also coming from the fact that I have multiple directories having the same module config. thank you

Create gitlab project from template with terraform provider

I want to crate a gitlab project from a template via terafrom code.
resource "gitlab_project" "services_projects" {
for_each = local.service_projects
name = "${each.key}"
default_branch = "main"
description = ""
issues_enabled = false
merge_requests_enabled = false
namespace_id = "${gitlab_group.services_group.id}"
snippets_enabled = false
visibility_level = "private"
wiki_enabled = false
use_custom_template = "${each.value.use_custom_template}"
template_project_id = "${each.value.template_project_id}"
group_with_project_templates_id = var.group_with_project_templates_id
}
This works, all my projects were crated and also the project to be created from template is created from the template. But then terraform errors with:
module.services["test_tf_1"].gitlab_project.services_projects["values"]: Destruction complete after 5s
75module.services["test_tf_1"].gitlab_project.services_projects["values"]: Creating...
76╷
77│ Error: error while waiting for project "values" import to finish: unexpected state 'failed', wanted target 'finished'. last error: %!s(<nil>)
78│
79│ with module.services["test_tf_bb_1"].gitlab_project.services_projects["values"],
80│ on modules/gitlab/main.tf line 132, in resource "gitlab_project" "services_projects":
81│ 132: resource "gitlab_project" "services_projects" {
82│
83╵
85
Cleaning up project directory and file based variables
00:01
87ERROR: Job failed: command terminated with exit code 1
Does anyone knows where this error comes from or how I can solve it?
I think it has something to do with the missing template_link but I don't really understand the concept. Creating one does not work.
https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs/resources/group_project_file_template
I think it's an issue of Gitlab itself, not your code/terraform provider.
Please see https://gitlab.com/gitlab-org/gitlab/-/issues/208452
It might be a flaky bug. In my case it helped simply to re-run the same code.

condition on terraform module

Trying to run modules conditionally.
Expectation : Run module only when env is not equal to prd
module "database_diagnostic_eventhub_setting" {
count = var.env != "prd" ? 1 : 0 // run block if condition is satisfied
source = "git::https://git_url//modules/...."
target_ids = [
"${data.terraform_remote_state.database.outputs.server_id}"
]
environment = "${var.environment}-database-eventhub"
destination = data.azurerm_eventhub_namespace_authorization_rule.event_hub.id
eventhub_name = var.eventhub_name
logs = [
"PostgreSQLLogs",
"QueryStoreWaitStatistics"
]
}
Error:
The name "count" is reserved for use in a future version of Terraform.
You need to use Terraform v0.13 or later in order to use count or for_each inside a module block.
If you can't upgrade from Terraform v0.12 then the old approach, prior to support for module repetition, was to add a variable to your module to specify the object count:
variable "instance_count" {
type = number
}
...and then inside your module add count to each of the resources:
resource "example" "example" {
count = var.instance_count
}
However, if you are able to upgrade to Terraform v0.13 now then I would strongly suggest doing so rather than using the above workaround, because upgrading to use module-level count later, with objects already created, is quite a fiddly process involving running terraform state mv for each of your resource in that module.

Terraform conditionally exclude a resource block

The below is specific to terraform .11 and works with .12
Below is the code I am using. It is a data block to get Image details from Azure shared Image Gallery.
I have a variable input parameter for image_version
I can give image_version as a particular version ( like * 1.0.1 or 1.0.2 * ) or can give input as * latest *
If you see the output block in below code , if the image_version is given as latest the 1st data section will be executed and latest image will be given as output
And if I give input NOT as latest - the 2nd data section will be executed and give that particular image ID will be given as output
So this output , I am using for virtual machine creation
### 1. latest section ####
data "azurerm_shared_image" "centos7" {
name = "centos"
gallery_name = "centos_galleries"
resource_group_name = "centos-galleries-rg"
}
### 2. image version number section ####
data "azurerm_shared_image_version" "centos7" {
name = "1.0.1" ## [ This block fails when provided a dummy number ]
image_name = "centos"
gallery_name = "centos_galleries"
resource_group_name = "centos-galleries-rg"
}
output "id" {
value = "${var.image_version == "latest" ? data.azurerm_shared_image.centos7.id : data.azurerm_shared_image_version.centos7.id}"
}
Now the issue is, in 2nd data section I am giving name = 1.0.1 - which should be an existing version in Shared Image gallery.
If I gives a non existing version number in my code ( say name = 10.10.10 ) and gives my input image_version = latest , ideally only the 1st data section should be evaluated and should be working fine - but with terraform 11 - the 2nd data section also gets evaluated and it is failing with the name = 10.10.10 version is not existing. Here I gave input image_version = latest - still it is failing
So is there a way I can conditionally exclude a complete data section or is there a better way I can re-write this code?

Terraform: list to string

I am trying to create a Security Group using terraform module terraform-aws-modules/security-group/aws. This would need VPC id which is taken from aws_vpcs data source. The VPC id requires a string value, but the aws_vpcs data source returns a list with a single value.
Please find
data "aws_vpcs" "this" {
tags = {
"Name" = "example"
}
}
module "route53_sg" {
source = "terraform-aws-modules/security-group/aws"
name = "R53_health_checkers"
description = "Security group for Route53 health checkers"
vpc_id = element([data.aws_vpcs.this.ids], 0)
ingress_cidr_blocks = [
...
...
...
]
ingress_rules = ["https-443-tcp"]
}
$ terraform apply
data.aws_lb.ext_alb: Refreshing state...
data.aws_vpcs.this: Refreshing state...
Error: Invalid value for module argument
on main.tf line 75, in module "route53_sg":
75: vpc_id = element([data.aws_vpcs.this.ids], 0)
The given value is not suitable for child module variable "vpc_id" defined at
.terraform/modules/route53_sg/terraform-aws-modules-terraform-aws-security-group-d55e4de/variables.tf:10,1-18:
string required.
vpc_id is expecting a Single string. FOLLOWING is a result from Output.tf
$ terraform apply
data.aws_lb.ext_alb: Refreshing state...
data.aws_vpcs.this: Refreshing state...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
vpc = [
"vpc-08067a598522a7b30",
]
data.aws_vpcs.this.ids is already a list, you don't need to put it into another list.
Try:
vpc_id = element(data.aws_vpcs.this.ids, 0)
EDIT: Answering questions from the comment:
It seems like the ids returned is a set instead of a list, as mentioned in a similar issue here:
https://github.com/terraform-providers/terraform-provider-aws/issues/7522
If you are using 0.12.x:
You can do
vpc_id = element(tolist(data.aws_vpcs.this.ids), 0)
If you are using 0.11.x: You can do
vpc_id = element(split(",", join(",", data.aws_vpcs.this.ids))), 0)

Resources