I am trying to use this provider, https://registry.terraform.io/providers/jgrumboe/restapi/1.18.3-dev
Which is a spin off of,
https://registry.terraform.io/providers/Mastercard/restapi/1.17.0
These providers let you automate APIs that follow REST standards to GET/POST/PUT and DELETE resources.
Now, the resource restapi_object allows you to specify, "data" that'll be used during a POST and "update_data" will be used during a PUT.
resource "restapi_object" "app_scripted_demo_client" {
provider = restapi.restapi_oauth
path = "/Applications"
data = jsonencode({
"Uuid": random_uuid.app_scripted_demo_client_uuid.id,
"Name": "Scripted Demo Client"
}
})
update_data = jsonencode({
"Uuid": random_uuid.app_scripted_demo_client_uuid.id,
"Name": "Scripted Demo Client 1",
"ApiKey": try(restapi_object.app_scripted_demo_client.api_data.ApiKey, "dummykey"),
"KeySecret": try(restapi_object.app_scripted_demo_client.api_data.KeySecret, "dummysecret")
}
})
}
update_data takes two vars called, ApiKey and KeySecret, that's created during a POST.
When I refer to them using the same resource I get errors like these,
│ Error: Self-referential block
│
│ on apps.tf line 49, in resource "restapi_object" "app_scripted_demo_client":
│ 49: "ApiKey": try(restapi_object.app_scripted_demo_client.api_data.ApiKey, "dummykey"),
│
│ Configuration for restapi_object.app_scripted_demo_client may not refer to itself.
I understand terraform doesn't know that "update_data" is only used after the resource is created.
Is there a way to circumvent the error?
I tried using local vars like this,
locals {
app_scripted_demo_client_key = try(restapi_object.app_scripted_demo_client.api_data.ApiKey, "dummykey")
app_scripted_demo_client_secret = try(restapi_object.app_scripted_demo_client.api_data.KeySecret, "dummysecret")
}
They throw a similar error like this,
│ Error: Cycle: local.app_scripted_demo_client_secret (expand), restapi_object.app_scripted_demo_client, local.app_scripted_demo_client_key (expand)
Related
My problem statement is simple but I am not able to find a solution anywhere on the internet.
I have users list as locals:
// users
locals {
allUsers = {
dev_user_1 = {
Name = "user1"
Email = "user1#abc.com"
GitHub = "user1" # github username
Team = "Dev"
}
devops_user_2 = {
Name = "user2"
Email = "user2#abc.com"
GitHub = "user2" # github username
Team = "DevOps"
}
product_user_3 = {
Name = "user3"
Email = "user3#abc.com"
Team = "Product"
}
}
}
These are the local tags that are being used for purposes of creating access to internal tools such as Github, Monitoring tools, etc.
Now, for the 2 users who belong to the Dev and DevOps team, they need access to Github ORG, while, the product user only needs access to some dashboards but not to Github, hence, the tag is missing.
How can I loop over the terraform resource github_membership to skip this product user (or simply anyone who does not have tag key GitHub?)
I am trying the following code, but no luck
// Send GitHub invite
resource "github_membership" "xyzTeam" {
for_each = local.allUsers
username = each.value.GitHub
role = "member"
}
Errors:
╷
│ Error: Unsupported attribute
│
│ on users.tf line 12, in resource "github_membership" "xyzTeam":
│ 12: username = each.value.GitHub
│ ├────────────────
│ │ each.value is object with 3 attributes
│
│ This object does not have an attribute named "GitHub".
What I did to solve this issue?
Set GitHub key for everyone but it's value as null.
Error:
╷
│ Error: "username": required field is not set
│
│ with github_membership.xyzTeam["user3"],
│ on users.tf line 10, in resource "github_membership" "xyzTeam":
│ 10: resource "github_membership" "devops" {
│
╵
If I left the value empty, errors:
Error: PATCH https://api.github.com/user/memberships/orgs/XYZ: 422 You can only update an organization membership's state to 'active'. []
for k, v in local.allUsers : k => v if v != ""
Same error because it tries to create the user with empty value still, and fails ultimately.
I cannot think of anything else. If someone can help to create separate locals from these existing locals, which creates the list of locals that grep the GitHub values, that hack would be super helpful.
You had the right idea with your third attempt, but the conditional logic in the for expression is slightly off. You need to use the can function instead:
{ for user, attributes in local.allUsers : user => attributes if can(attributes.GitHub) }
If the nested map contains a Github key, then can(attributes.Github) returns true, and the map constructor will contain the key-value pair. With this algorithm, you can construct a new map from the old map with the entries removed that do not contain a Github key in the nested map value.
Hello I am trying to create a azuread_application_password for azuread_application to use it for authentication during backend configuration.
resource "azuread_application_password" "application_password" {
application_object_id = azuread_application.app-tf.object_id
end_date = timeadd(timestamp(), "720h")
}
output "client_secret" {
description = "Client Secret"
value = azuread_application_password.application_password.value
}
Since I am doing the provisioning through terraform, I need to see the application_password or client_secret after creation so I can use that value.
│ Error: Output refers to sensitive values
│
│ on main.tf line 47:
│ 47: output "client_secret" {
│
│ To reduce the risk of accidentally exporting sensitive data that was intended to be only internal, Terraform requires
│ that any root module output containing sensitive data be explicitly marked as sensitive, to confirm your intent.
│
│ If you do intend to export this data, annotate the output value as sensitive by adding the following argument:
│ sensitive = true
I understand this might now be safest, but I believe that is only way to create and retrieve client_secret while using terraform, so how can I work around this error and get the value?
Use nonsensitive function to disable masking:
output "client_secret" {
description = "Client Secret"
value = nonsensitive(azuread_application_password.application_password.value)
}
I have a simple data source block to retrieve a WAF policy resource but it doesn't find the resource. If I comment out the data block there is no problem. The WAF policy created by terraform can be applied and destroyed.
data "azurerm_web_application_firewall_policy" "example" {
name = "a205555-az-waf-policy"
resource_group_name = "eastus2-204161-platform-resources"
}
output "azurerm_web_application_firewall_policy" {
value = data.azurerm_web_application_firewall_policy.example.id
}
When I try to get the resource data I get error:
│ Error: Error: Web Application Firewall Policy "a205555-az-waf-policy" was not found
│ with data.azurerm_web_application_firewall_policy.example,
│ on output.tf line 40, in data "azurerm_web_application_firewall_policy" "example":
│ 40: data "azurerm_web_application_firewall_policy" "example" {
│
I've tried removing the resource from tfstate, importing the resource, deleting and recreating it, upgrading the provider in case there was a bug. Any ideas?
I am getting error on "This value does not have any attributes.". How do I setup dependencies that module vpc must runs prior?
From the main file I call the following modules
module "vpc" {
source = "../../modules/vpc"
environment = "demo"
}
module "eks-cluster" {
source = "../../modules/eks-cluster"
environment = "demo"
vpc_id = module.vpc.my_vpc_id
my_public_subnets = module.vpc.my_public_subnets_id
}
main.tf within ../../modules/eks-cluster
resource "aws_eks_cluster" "research-cluster" {
name = var.my_cluster_name
role_arn = aws_iam_role.research-cluster.arn
vpc_config {
security_group_ids = [aws_security_group.research-cluster.id]
subnet_ids = var.my_public_subnets.id
}
Error I am getting
╷
│ Error: Unsupported attribute
│
│ on ../../modules/eks-cluster/main.tf line 79, in resource "aws_eks_cluster" "demo-cluster":
│ 79: subnet_ids = var.my_public_subnets.id
│ ├────────────────
│ │ var.my_public_subnets is a list of string, known only after apply
│
│ This value does not have any attributes.
In general, terraform is able to handle dependencies properly in 99% of all cases, but you can still set artificial dependencies by using the depends_on meta-argument - for this to work your terraform version should be => 0.13.
By using your code snippet, it would be something like:
module "eks-cluster" {
depends_on = [module.vpc]
source = "../../modules/eks-cluster"
environment = "demo"
vpc_id = module.vpc.my_vpc_id
my_public_subnets = module.vpc.my_public_subnets_id
}
However, by the looks of it, it very well may be the way your outputs are set up in the vpc module, or the way your variables are set in the eks-cluster module.
I'm on TF version v1.0.0(latest) and am trying to make use of the pagerduty Tf provider and the error log says could not retrieve teh list of available versions. Below is the code snippet and complete error log.
Code:
terraform {
required_providers {
pagerduty = {
source = "PagerDuty/pagerduty"
version = "~> 1.9.8"
}
}
}
provider "pagerduty" {
token = var.token
}
resource "pagerduty_service" "example" {
name = "My Web App"
auto_resolve_timeout = 14400
acknowledgement_timeout = 600
escalation_policy = var.policy
}
resource "pagerduty_service_integration" "apiv2" {
name = "API V2"
type = "events_api_v2_inbound_integration"
service = pagerduty_service.example.id
}
Error:
- Finding latest version of hashicorp/pagerduty...
╷
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/pagerduty: provider registry
│ registry.terraform.io does not have a provider named registry.terraform.io/hashicorp/pagerduty
│
│ Did you intend to use pagerduty/pagerduty? If so, you must specify that source address in each module which
│ requires that provider. To see which modules are currently depending on hashicorp/pagerduty, run the following
│ command:
│ terraform providers
Answering my question.
Separating the first terraform required_providers blocks into its own versions.tf file has solved the issue.