Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App deployment prevents database firewall setup #841

Open
LouisIV opened this issue Jun 19, 2022 · 5 comments
Open

App deployment prevents database firewall setup #841

LouisIV opened this issue Jun 19, 2022 · 5 comments
Assignees
Labels

Comments

@LouisIV
Copy link

LouisIV commented Jun 19, 2022

Bug Report


Currently I have a configuration like:

resource "digitalocean_app" "foo" {
   ...
   database {
      cluster_name = digitalocean_database_cluster.mysql.name
      db_name      = digitalocean_database_db.database-stage.name
      db_user      = digitalocean_database_user.agnew-user.name
      engine       = "MYSQL"
      version      = digitalocean_database_cluster.mysql.version
      name         = "mysql"
      production   = true
    }
}

resource "digitalocean_database_firewall" "app-fw" {
  cluster_id = digitalocean_database_cluster.mysql.id

  rule {
    type  = "app"
    value = digitalocean_app.foo.id
  }

  rule {
    type  = "vpc"
    value = var.vpc_id
  }
}

I have a worker that connects to the database and runs migrations before the app deploys. The issue is that as far as I can tell the app deployment needs to pass before I can get the app id. The migration container can't pass unless it can connect to the database, which it can't do because it's not trusted.

Is there any workaround for this?

Describe the bug

Affected Resource(s)

Expected Behavior

Actual Behavior

Steps to Reproduce

Terraform Configuration Files

Expected behavior

Debug Output

Panic Output

Additional context

Important Factoids

References

@LouisIV LouisIV added the bug label Jun 19, 2022
@Igosuki
Copy link

Igosuki commented Jun 20, 2022

Came here looking for similar issues, but it's not a bug. I think the solution is to put the instance count of both the service and the job at zero then re-apply with 1

Edit : Nevermind, instance count can never be zero. Chicken and egg problem...

@LouisIV
Copy link
Author

LouisIV commented Jun 20, 2022

Part of me thought I might be able to do something with a local_exec provisioner. If I had the ID I could send a GraphQL request to the API along the lines of:

  {
    "operationName": "DBaaSSetFirewallRules",
    "variables": {
        "payload": {
            "cluster_name": "mysql",
            "cluster_uuid": "--------",
            "rules": [
                {
                    "name": "agnew",
                    "value": "-----------",
                    "type": "APP"
                }
            ]
        }
    },
    "query": "mutation DBaaSSetFirewallRules($payload: FirewallRulesRequest) {\n  DBaaSSetFirewallRules(FirewallRulesRequest: $payload)\n}\n"
}

But I can't get the ID until app deploys. Not sure if this applies to the local_exec provisioner though

@LouisIV
Copy link
Author

LouisIV commented Jun 20, 2022

I really don't like this but I was able to get something working (still running) with dynamic blocks. Basically I deployed the app with nothing that would need to access the database (you could use an empty nginx container for this for example)

resource "digitalocean_app" "foo" {
...
 dynamic "job" {
      for_each = toset(digitalocean_database_cluster.mysql != null ? ["fake"] : [])
      content {
        ...
    }
...
}

resource "digitalocean_database_firewall" "foo-fw" {
  cluster_id = digitalocean_database_cluster.mysql.id

  rule {
    type  = "app"
    value = digitalocean_app.foo.id
  }
}

In theory this should deploy the database, the app, and then setup the firewall. You could then come back in with a second apply and get your stuff setup since the database will exist by then. This is not an acceptable workaround though since it won't work if anything fails after the database has been created.

Not requiring an active deployment for an app import would go a long way here.

@Igosuki
Copy link

Igosuki commented Jun 21, 2022

I'd go further, the functionality is useless if one cannot import an app without a deployment... As long as the app spec exists so should the tfstate corresponding to the app resource.

@andrewsomething
Copy link
Member

Thanks for flagging this problem for us. I think it brings up some larger questions about how/if Terraform should be handling the state of deployments. The PR at #843 doesn't completely address this issue, but it will allow importing existing apps without an active deployment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants