SAP / terraform-provider-btp

Terraform provider for SAP BTP
https://registry.terraform.io/providers/SAP/btp/latest
Apache License 2.0
83 stars 17 forks source link

[BUG] Error after switch to release 0.2.0 #334

Closed MatanElitzur closed 1 year ago

MatanElitzur commented 1 year ago

Is there an existing issue for this?

What version of Terraform are you using?

0.2.0-beta2

What type of issue are you facing

bug report

Describe the bug

Invoking the apply command on an existing subaccount created with the 0.1.0-beta1 version I got the following error log

Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ReadResource call. The plugin logs may contain more details.
╵

Stack trace from the terraform-provider-btp_v0.2.0-beta2 plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xb07641]

goroutine 371 [running]:
github.com/SAP/terraform-provider-btp/internal/provider.(*subaccountEntitlementResource).Read(0xc0003f60d8, {0xe09d10, 0xc000495080}, {{{{0xe0e2d0, 0xc000545ce0}, {0xbd36a0, 0xc000545c20}}, {0xe10940, 0xc000177040}}, 0xc0003f60e8, ...}, ...)
        github.com/SAP/terraform-provider-btp/internal/provider/resource_subaccount_entitlement.go:154 +0x421
github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).ReadResource(0xc0000c14a0, {0xe09d10, 0xc000495080}, 0xc000495140, 0xc00044b648)
        github.com/hashicorp/terraform-plugin-framework@v1.3.3/internal/fwserver/server_readresource.go:101 +0x677
github.com/hashicorp/terraform-plugin-framework/internal/proto6server.(*Server).ReadResource(0xc0000c14a0, {0xe09d10?, 0xc000494000?}, 0xc0008638c0)
        github.com/hashicorp/terraform-plugin-framework@v1.3.3/internal/proto6server/server_readresource.go:55 +0x41a
github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server.(*server).ReadResource(0xc0001b26e0, {0xe09d10?, 0xc0003fa720?}, 0xc00015b7a0)
        github.com/hashicorp/terraform-plugin-go@v0.18.0/tfprotov6/tf6server/server.go:749 +0x4b1
github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6._Provider_ReadResource_Handler({0xc96b00?, 0xc0001b26e0}, {0xe09d10, 0xc0003fa720}, 0xc000126690, 0x0)
        github.com/hashicorp/terraform-plugin-go@v0.18.0/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go:386 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0001ae1e0, {0xe0ec78, 0xc0001bfd40}, 0xc0005b25a0, 0xc000314180, 0x12c7e90, 0x0)
        google.golang.org/grpc@v1.56.1/server.go:1337 +0xdf3
google.golang.org/grpc.(*Server).handleStream(0xc0001ae1e0, {0xe0ec78, 0xc0001bfd40}, 0xc0005b25a0, 0x0)
        google.golang.org/grpc@v1.56.1/server.go:1714 +0xa36
google.golang.org/grpc.(*Server).serveStreams.func1.1()
        google.golang.org/grpc@v1.56.1/server.go:959 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
        google.golang.org/grpc@v1.56.1/server.go:957 +0x18c

Error: The terraform-provider-btp_v0.2.0-beta2 plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Expected Behavior

No response

Steps To Reproduce

No response

Add screenshots to help explain your problem

No response

Additional context

No response

lechnerc77 commented 1 year ago

@MatanElitzur Can you please add information on how to reproduce the scenario:

At best attach the Terraform configuration files you used (remove any sensitive information).

v0lkc commented 1 year ago

As @lechnerc77 already said, without knowing the exact environment it's pretty hard to reproduce. This is what I've just tried in live, with the latest provider version:

resource "btp_subaccount" "trial" {
  name      = "My Subaccount"
  subdomain = "my-trial-subdomain"
  region    = "us10"
}

resource "btp_subaccount_entitlement" "alert" {
  subaccount_id = btp_subaccount.trial.id
  service_name  = "alert-notification"
  plan_name     = "standard"
}

But it works.

MatanElitzur commented 1 year ago

provider.tf

terraform {
  required_providers {
    btp = {
      source  = "SAP/btp"
      #version = "0.1.0-beta1"
      version = "0.2.0-beta2"
    }
  }
}

# Configure the BTP Provider
provider "btp" {
  # https://registry.terraform.io/providers/SAP/btp/latest/docs
  # If you want to run in canary, you have to additionally specify the cli api url of canary 'cli_server_url',
  # it’s basically the same configuration you would expect for the btp cli
  cli_server_url = "https://cpcli.cf.sap.hana.ondemand.com"
  globalaccount = var.global_account
  username = var.username
  password = var.password
}

variables.tf

variable "emergency_admins" {
  type        = list(string)
  description = "Defines the colleagues who are added to each subaccount as emergency administrators."
  default = ["matan.elitzur@sap.com", "oren.frishberg.barak@sap.com"]
}

###
# Entitlements
###
variable "entitlements" {
  description = "List of entitlements for a BTP subaccount"
    type = list(object({
      group = string
      type  = string
      name = string
      plan = string
      amount = number
  }))

  default = [
    {
      group = "Object Store"
      type  = "service"
      name = "objectstore"
      plan = "s3-standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Application Logging Service"
      type  = "service"
      name = "application-logs"
      plan = "standard"
      amount = 3
    },
    {
      group = "Cloud Foundry Runtime"
      type  = "service"
      name = "APPLICATION_RUNTIME"
      plan = "MEMORY"
      amount = 100 #To do change back to 300; 300 is the default
    },
    {
      group = "auditlog"
      type  = "service"
      name = "auditlog"
      plan = "standard"
      amount = 10
    },
    {
      group = "Cloud Management Service"
      type  = "service"
      name = "cis"
      plan = "system-basic"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Connectivity Service"
      type  = "service"
      name = "connectivity"
      plan = "lite"
      amount = null # When you have a 1 shared units
    },
    {
      group = "SAP Content Agent Service"
      type  = "service"
      name = "content-agent"
      plan = "application"
      amount = null # When you have a 1 shared units
    },
    {
      group = "SAP Content Agent Service"
      type  = "service"
      name = "content-agent"
      plan = "standard"
      amount = 1
    },
    {
      group = "Credential Store"
      type  = "service"
      name = "credstore"
      plan = "medium"
      amount = 10
    },
    {
      group = "Destination Service"
      type  = "service"
      name = "destination"
      plan = "lite"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Feature Flags"
      type  = "service"
      name = "feature-flags-dashboard"
      plan = "dashboard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Feature Flags"
      type  = "service"
      name = "feature-flags"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Feature Flags"
      type  = "service"
      name = "feature-flags"
      plan = "lite"
      amount = null # When you have a 1 shared units
    },
    {
      group = "File System"
      type  = "service"
      name = "fs-storage"
      plan = "custom"
      amount = 10
    },
    {
      group = "HTML5 Application Repository Service"
      type  = "service"
      name = "html5-apps-repo"
      plan = "app-host"
      amount = null # When you have a 1 shared units
    },
    {
      group = "HTML5 Application Repository Service"
      type  = "service"
      name = "html5-apps-repo"
      plan = "app-runtime"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Cloud Identity Services"
      type  = "service"
      name = "identity"
      plan = "application"
      amount = 1
    },
    {
      group = "Job Scheduling Service"
      type  = "service"
      name = "jobscheduler"
      plan = "lite"
      amount = 8
    },
    {
      group = "Job Scheduling Service"
      type  = "service"
      name = "jobscheduler"
      plan = "standard"
      amount = 4
    },
    {
      group = "SAP Malware Scanning Service"
      type  = "service"
      name = "malware-scanner"
      plan = "clamav"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Message Queuing"
      type  = "service"
      name = "message-queuing"
      plan = "standard"
      amount = 3
    },
    {
      group = "Mobile Services"
      type  = "service"
      name = "mobile-services"
      plan = "standard"
      amount = 3
    },
    {
      group = "Cloud Portal Service"
      type  = "service"
      name = "portal"
      plan = "standard"
      amount = 3
    },
    {
      group = "PostgreSQL, hyperscaler option"
      type  = "service"
      name = "postgresql-db"
      plan = "development"
      amount = 3
    },
    {
      group = "Redis, hyperscaler option"
      type  = "service"
      name = "redis-cache"
      plan = "development"
      amount = 3
    },
    {
      group = "SaaS Provisioning Service"
      type  = "service"
      name = "saas-registry"
      plan = "application"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Service Manager"
      type  = "service"
      name = "service-manager"
      plan = "service-operator-access"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Service Manager"
      type  = "service"
      name = "service-manager"
      plan = "ssubaccount-audit"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Service Manager"
      type  = "service"
      name = "service-manager"
      plan = "subaccount-admin"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Service Manager"
      type  = "service"
      name = "service-manager"
      plan = "container"
      amount = 1
    },
    {
      group = "Service Manager APIs"
      type  = "service"
      name = "service-manager-api"
      plan = "subaccount-developer"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Subscription Manager"
      type  = "service"
      name = "subscription-manager"
      plan = "provider"
      amount = null # When you have a 1 shared units
    },
    {
      group = "UI Theme Designer"
      type  = "service"
      name = "theming"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "UI5 Flexibility Design and Configuration"
      type  = "service"
      name = "ui5-flexibility-design-and-configuration"
      plan = "design-and-configuration"
      amount = 3
    },
    {
      group = "UI5 flexibility for key users"
      type  = "service"
      name = "ui5-flexibility-keyuser"
      plan = "keyuser"
      amount = 9
    },
    {
      group = "UI5 Flexibility Personalization Service"
      type  = "service"
      name = "ui5-flexibility-personalization"
      plan = "personalization"
      amount = 5
    },
    {
      group = "Workflow"
      type  = "service"
      name = "workflow"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "XFS Runtime"
      type  = "service"
      name = "xfs-runtime"
      plan = "default"
      amount = 3
    },
    # { We get xsuaa from the platform we don't need to config it
    #   group = "Authorization and Trust Management Service"
    #   type  = "service"
    #   name = "xsuaa"
    #   plan = "application"
    #   amount = null # When you have a 1 shared units
    # },
    # { We get xsuaa from the platform we don't need to config it
    #   group = "Authorization and Trust Management Service"
    #   type  = "service"
    #   name = "xsuaa"
    #   plan = "broker"
    #   amount = 1
    # },
    {
      group = "Authorization and Trust Management Service"
      type  = "service"
      name = "xsuaa"
      plan = "space"
      amount = 1
    },
    {
      group = "Authorization and Trust Management Service"
      type  = "service"
      name = "xsuaa"
      plan = "apiaccess"
      amount = null # When you have a 1 shared units
    },
    #### Need to check where it's come from
    {
      group = "Cloud Integration Automation Service"
      type  = "service"
      name = "cias"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Cloud Integration Automation Service"
      type  = "service"
      name = "cias"
      plan = "oauth2"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Print Service"
      type  = "service"
      name = "print"
      plan = "receiver"
      amount = null # When you have a 1 shared units
    },
    {
      group = "Master Data Integration"
      type  = "service"
      name = "one-mds"
      plan = "sap-integration"
      amount = 1
    },
    {
      group = "Custom Domain Service"
      type  = "service"
      name = "INFRA"
      plan = "custom_domains"
      amount = 1
    },
    {
      group = "SAP Build Work Zone, advanced edition"
      type  = "service"
      name = "build-workzone-advanced"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "SAP Build Work Zone, advanced edition"
      type  = "service"
      name = "SAPWorkZone"
      plan = "standard"
      amount = null # When you have a 1 shared units
    },
    {
      group = "SAP Build Work Zone, standard edition"
      type  = "service"
      name = "SAPLaunchpad"
      plan = "free"
      amount = 1
    },
    {
      group = "SAP Build Work Zone, standard edition"
      type  = "service"
      name = "SAPLaunchpad"
      plan = "standard"
      amount = 200
    },
    {
      group = "Cloud Portal Service"
      type  = "service"
      name = "PortalApplication"
      plan = "standard"
      amount = 60
    },
  ]
}

###
# Possible values for entering the business unit
###
variable "unit" {
  type        = string
  description = "Defines to which organisation the sub account shall belong to."
  default     = "Research"

  validation {
    condition = contains(concat(["Research", "Test", "Sales", "Purchase", "Production"]), var.unit)
    error_message = "Please select a valid org name for the project account."
  }
}

###
# Sub account name of BTP sub account
###
variable "sub_account_name" {
  type        = string
  description = "The name of the subaccount."
  default     = "Test sub domain"
}

###
# Subdomain of BTP sub account
###
variable "sub_account_domain" {
  type        = string
  description = "The subdomain of the subaccount."
  default     = "test-sub-domain"
}

###
# Region of BTP sub account
###
variable "region" {
  type        = string
  description = "The region where the sub account shall be created in."
  default     = "eu12"
}

###
# Global account of BTP sub account
###
variable "global_account" {
  type        = string
  description = "The global account where the sub account shall be owned."
  default     = "portal-devops-ci"
}

###
# Username of BTP sub account
###
variable "username" {
  type        = string
  description = "The username for the login."
  default     = "sapeuxautomation@sap.com"
}

###
# Password of BTP sub account
###
variable "password" {
  type        = string
  description = "The password for the login username."
  default     = <*********>
}

main.tf

locals {
  #project_subaccount_name   = "${var.unit_shortname}_${var.stage}"
  #project_subaccount_domain = lower(replace("${local.project_subaccount_name}", "_", "-"))
  project_subaccount_cf_org = replace(join("_", ["${var.unit}", "${var.sub_account_domain}"]), " ", "_")
}

#Returns information about the logged-in user.
data "btp_whoami" "me" {}

# # create a subaccount in eu12
# resource "btp_subaccount" "test-sub-domain-resource" {
#   name      = "Test sub domain"
#   subdomain = "test-sub-domain"
#   region    = "eu12"
# }

# create a subaccount
resource "btp_subaccount" "project" {
  name      = var.sub_account_name
  subdomain = var.sub_account_domain
  region    = var.region
}

###
# Assignment of emergency admins to the sub account as sub account administrators
###
resource "btp_subaccount_role_collection_assignment" "subaccount_users" {
  for_each = toset("${var.emergency_admins}")
    subaccount_id        = btp_subaccount.project.id
    role_collection_name = "Subaccount Administrator"
    user_name     = each.value
}

# resource "btp_subaccount_trust_configuration" "fully_customized" {
#   subaccount_id     = btp_subaccount.project.id
#   identity_provider = var.custom_idp
# }

###
# Creation of Cloud Foundry environment
###
module "cloudfoundry_environment" {
  source = "github.com/SAP-samples/btp-terraform-samples/released/modules/envinstance-cloudfoundry/"
  subaccount_id         = btp_subaccount.project.id
  instance_name         = local.project_subaccount_cf_org
  cloudfoundry_org_name = local.project_subaccount_cf_org
}

###
# Add entitlements
###
resource "btp_subaccount_entitlement" "entitlements" {
  for_each   = {
    for index, entitlement in var.entitlements:
    index => entitlement
  }

  subaccount_id = btp_subaccount.project.id
  service_name  = each.value.name
  plan_name     = each.value.plan
  amount        = each.value.amount #Matan added
}
v0lkc commented 1 year ago

Ok, from your script I can see you're using canary. But even there I'm unfortunate not able to reproduce this issue, I can just guess. It could have sth to do with the way how you iterate over the entitlements to be setup. You don't want to use the index as resource identifier here, since its way to unstable. Everytime you add a new entitlement to the list, it potentially impacts all the other entitlements. Instead either go with individual btp_subaccount_entitlement resources, or use the service_name and plan_name as combined key like this:

resource "btp_subaccount_entitlement" "entitlements" {
  for_each   = { 
    for index, entitlement in var.entitlements:
    "${entitlement.name}:${entitlement.plan}" => entitlement
  }

  subaccount_id = btp_subaccount.trial.id
  service_name  = each.value.name
  plan_name     = each.value.plan
  amount        = each.value.amount #Matan added
}