alekc / terraform-provider-auth0

Mozilla Public License 2.0
18 stars 7 forks source link

Best practise to deploy actions and flow - possible bug? #30

Closed xanonid closed 2 years ago

xanonid commented 2 years ago

I am trying to deploy an action with dependencies, but get sometimes following error:

auth0_action.my_action Modifying... [id=ea3aa214-c021-4063-b71c-e974609849ca]
auth0_action.my_action Still modifying... [id=ea3aa214-c021-4063-b71c-e974609849ca, 10s elapsed]
auth0_action.my_action Still modifying... [id=ea3aa214-c021-4063-b71c-e974609849ca, 20s elapsed]
auth0_action.my_action Still modifying... [id=ea3aa214-c021-4063-b71c-e974609849ca, 30s elapsed]
╷
│ Error: 400 Bad Request: A draft must be in the 'built' state before it can be deployed.
│ 
│   with auth0_action.my_action,
│   on actions.tf line 10 in resource "auth0_action" "my_action":
│   12: resource "auth0_action" "my_action" {
│ 
╵

I use deploy = true. It seems also that actions which are not yet built cannot be used in auth0_flow resources such that multiple terraform apply are sometimes needed.

Is this a bug in the provider or is there a mechanism to wait until actions are properly built? It would be nice to have a working minimal example somewhere documented.

alekc commented 2 years ago

@xanonid can you paste the affected terraform code please?

alekc commented 2 years ago

Also, this is an example from the acceptance test (ignore the {{random}} field)

resource "auth0_action" "myaction" {
    name = "Acceptance Test - Action - {{.random}}"
    trigger {
        id = "{{ .trigger_id }}"
    }
    code = "exports.onExecutePostLogin = async (event, api) => {};"
    deploy = true
}
resource "auth0_action" "myaction2" {
    name = "Acceptance Test - Action2 - {{.random}}"
    trigger {
        id = "{{ .trigger_id }}"
    }
    code = "exports.onExecutePostLogin = async (event, api) => {};"
    deploy = true
}
resource "auth0_flow" "bind"{
    trigger_id =  "{{ .trigger_id }}"
    action {
        display_name = "action1"
        id = "${auth0_action.myaction.id}"
    }
    action {
        display_name = "action2"
        name = "${auth0_action.myaction2.name}"
    }
}

Long story short, the action has to be deployed and referenced from the flow by either depends_on or through usage of id like in my case. Terraform then will know that it have to create the action before creating a flow.

xanonid commented 2 years ago

Thanks for your repy. I tried it basically the same.

But if I a add a bigger dependency to your example, I get

auth0_action.myaction2: Creating...
auth0_action.myaction: Creating...
auth0_action.myaction2: Still creating... [10s elapsed]
auth0_action.myaction: Still creating... [10s elapsed]
auth0_action.myaction2: Still creating... [20s elapsed]
auth0_action.myaction: Still creating... [20s elapsed]
auth0_action.myaction2: Still creating... [30s elapsed]
auth0_action.myaction: Still creating... [30s elapsed]
╷
│ Error: 400 Bad Request: A draft must be in the 'built' state before it can be deployed.
│ 
│   with auth0_action.myaction,
│   on test.tf line 1, in resource "auth0_action" "myaction":
│    1: resource "auth0_action" "myaction" {
│ 
╵
╷
│ Error: 400 Bad Request: A draft must be in the 'built' state before it can be deployed.
│ 
│   with auth0_action.myaction2,
│   on test.tf line 15, in resource "auth0_action" "myaction2":
│   15: resource "auth0_action" "myaction2" {
│ 
╵

It seems that deploy = true triggers already the bug, without the auth0_flow.

Here the example (I do not actually use bit-bin but it is big enough to trigger the error reliable):

resource "auth0_action" "myaction" {
  name = "Acceptance Test - Action - 123"
  trigger {
    id = "post-login"
  }
  dependency {
    name    = "bit-bin"
    version = "14.8.8"
  }
  code   = "exports.onExecutePostLogin = async (event, api) => {};"
  deploy = true
}
resource "auth0_action" "myaction2" {
  name = "Acceptance Test - Action2 - 123"
  trigger {
    id = "post-login"
  }
  dependency {
    name    = "bit-bin"
    version = "14.8.8"
  }
  code   = "exports.onExecutePostLogin = async (event, api) => {};"
  deploy = true
}
resource "auth0_flow" "bind" {
  trigger_id = "post-login"
  action {
    display_name = "action1"
    id           = auth0_action.myaction.id
  }
  action {
    display_name = "action2"
    name         = auth0_action.myaction2.name
  }
}
alekc commented 2 years ago

@xanonid sorry for the delay, I've missed your reply.

By the first look, it feels like there is a race condition where from terraform point of view, those 2 actions are created and published, but for auth0 they are not.

I will introduce the waiting period for the flow where it will reattempt to publish for X times with interval of Y seconds. Lets see if that helps.

alekc commented 2 years ago

So, @xanonid , I did some investigation.

Good news: now actions creations will wait for them to become "built" before moving over to eventual deployment. Bad news: I've tried the bit-bin dependency on Auht0 website, and it fails there as well. My suspition is that they have some limits (not documented) which prevent large dependencies to be deployed.

xanonid commented 2 years ago

@alekc Thanks for investigating and making the PR. I tried it and it solves in most cases the deployment. Still, sometimes I get the error:

Error: unexpected state 'packaged', wanted target 'built'. last error: %!s()

Maybe, this case is still missing in the code. Otherwise, I would be glad of it could soon merged and released.

The bit-bin dependency might be really to big, it just was for reproducing the initial error more reliably.

alekc commented 2 years ago

@xanonid sorry for the delay and thanks for pointing out the "packaged state".

The change has been merged to master, expect a release in couple of days (I want to add some additional bits as well).