-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Initial commit for postgresql provider #3653
Conversation
Over in #3122 I called the database resource In other naming discussions we've leaned towards spelling things out in full to make them clearer, unless the abbreviation is part of a brand name or often used in the provider's own documentation. The Google DB resource is named So right now it seems like there is no consistent existing precedent. In that case, I think I'd lean towards the "spelling things out is better" convention and suggest we call this thing |
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: false, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know Postgres too well so please forgive me if this is a strange question: in Terraform resources we usually try to keep the number of required fields down to a minimum so that the "simple case" of configuration is as small as possible. Is it acceptable to leave owner
unset and have Postgres e.g. assume ownership by the user that was specified in the provider configuration?
On the other hand, if setting the owner on a database is something a Postgres user would expect to alwayss have to do then I think that's fine. 😄
This looks like a great start! Thanks @chelarua . I had some small feedback/questions inline but overall this looks great. If you'd like to also take a pass at documentation, you can get set up with the docs server relatively easily by running I didn't get a chance to test this provider yet since I don't have a Postgres environment to hand. I expect I can get set up with postgres on RDS to test but sadly I don't have the cycles to figure that out today, so I'll have to defer that for another time. |
@apparentlymart thanks for your review, I did some changes and added documentation too. |
case err != nil: | ||
return fmt.Errorf("Error reading info about database: %s", err) | ||
default: | ||
d.Set("owner", owner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do CREATE DATABASE
without the WITH OWNER
clause above, and then we read here, will this get populated with a default owner?
If so, it's important to mark the owner
argument as both Optional
and Computed
. This tells Terraform that the user can optionally override it (the Optional
part) but if they don't then the value will be computed based on something the server knows.
Thanks for the follow-up, @chelarua! I left some more feedback on the new code for making the owner optional. Almost done, I think! |
Hi, thanks for the suggestions again, i wasn't aware of that. I extended the test with a second database without explicit owner and indeed it was failing without the computed field set. |
@chelarua when you create a role with login permissions, how is the password set? I suspect we are still missing this. |
@apparentlymart could you do another review so @chelarua can resolve the last issues? |
encryptedCfg := getEncryptedStr(d.Get("encrypted").(bool)) | ||
|
||
query := fmt.Sprintf("ALTER ROLE %s %s PASSWORD '%s'", pq.QuoteIdentifier(roleName), encryptedCfg, password) | ||
_, err := conn.Query(query) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In cases like this where you need to do multiple calls to update different parts of the object, and each one of these calls can separately fail, it's good to use a ResourceData
mechanism called partial state, which in the event of an error allows Terraform to understand which values have been updated and which haven't, and thus reflect the current values in the state.
The pattern for partial state works like this:
- At the top of this function, before the first
HasChange
test, enable partial state mode by callingd.Partial(true)
. - After each one of these conditional calls succeeds, record the partial update by calling (for example)
d.SetPartial("password")
. - Just before the
return
statement at the very end of the function, calld.Partial(false)
to disable partial mode.
This patch is shaping up nicely! Thanks for the continued work on it @chelarua, and for the suggestions @ringods. Just another small bit of feedback on this one. I'm going to try to find some time soon to get set up with a Postgres instance so I can try running the tests. (I'm a total Postgres newbie!) |
@apparentlymart your last comments have been processed by @chelarua, my developer & colleague at @ReleaseQueue. Looking forward to your own Postgres test results so this can eventually be merged. |
Thanks for the latest round of updates. This looks great! I created a Postgres instance in Amazon RDS to test this. I mostly just accepted the default settings for a small RDS instance that would be free tier eligible, and asked for the username to be "matkins" and set a password. I then tried the following config (I've obscured parts of it that represent credentials or identifying info): provider "postgresql" {
host = "matkins-postgres-test.xxxxx.us-west-2.rds.amazonaws.com"
port = 5432
username = "matkins"
password = "xxxxx"
}
resource "postgresql_database" "main" {
name = "terraform_test"
} When I tried to apply this config I got this error:
I got a very similar result when I ran the acceptance tests from this patch against the same RDS instance, apparently when testing the
Do either of you see what I'm doing wrong here? |
@apparentlymart when you created the instance on the AWS console, did you specify a |
@ringods I didn't specify a database in the RDS UI since I was expecting that I'd be creating the database using this provider. Was I supposed to put my username in as the database name? Is every user expected to have a corresponding database of the same name? Again I must apologize for being a total PostgreSQL newbie here. I just followed the same pattern I've used to make MySQL RDS instances in the past, where I made the actual databases using the similar MySQL provider I worked on in #3122. |
@apparentlymart no problem being a newbie. I'm not gonna call myself an expert either. :-) When a PostgreSQL server is set up, the default administrative database is called Expect an additional commit to this pull request to fix this. |
I'm seeing another issue when running against a RDS instance, especially the micro versions, it seems that running the tests is quickly eating up all the allowed connections to the PostgreSQL server, which is 26 for the micro versions. I don't have that much experience with terraform plugins and i'm not sure exactly which is the mechanism for closing the connections, maybe @apparentlymart you can point me in the right direction on this one. |
@apparentlymart we figured out that for the 7 tests in this provider, each test calls 4 times into the It talks about MySQL, but it's the same approach for PostgreSQL. We are now experimenting with the ResourceProviderCloser interface to see if we can close the db connection correctly in there. |
Currently Terraform is leaking goroutines and with that memory. I know strictly speaking this maybe isn’t a real concern for Terraform as it’s mostly used as a short running command line executable. But there are a few of us out there that are using Terraform in some long running processes and then this starts to become a problem. Next to that it’s of course good programming practise to clean up resources when they're not needed anymore. So even for the standard command line use case, this seems an improvement in resource management. Personally I see no downsides as the primary connection to the plugin is kept alive (the plugin is not killed) and only unused connections that will never be used again are closed to free up any related goroutines and memory.
Hmm interesting... there are some existing examples where Terraform has to abide by either a rate limit or a fixed number of concurrent connections, but in the cases I've worked with that has been handled mainly by the underlying client library. I don't have much experience with Go's So perhaps a reasonable solution is to extend the provider configuration schema with a As you guys saw there are currently some problems with Terraform not necessarily closing connections opened by providers, but since connections are managed internally by the |
Thanks for the suggestion. I've made some tests with the SetMaxOpenConns, but it seems that limiting the connections is causing it to deadlock. It will output this continuously and never finish:
I think this is because it only will close the connections on exit. |
@apparentlymart we will take the route to open/close the db connection on resource manipulation. But for me the question still remains how the test framework behaves. While the |
The acceptance test harness executes a few different operations in sequence. It wants to see what happens when it applies the config and when it refreshes after applying the config at least. It also wants to destroy all of the resources it makes during testing. I must admit I've never looked closely at the details of what the acceptance test harness does, but I think the above could explain at least three complete runs through a Terraform lifecycle, each of which would re-configure the provider as if a user had run Terraform separately several times, with different options. |
@apparentlymart seems a fair explanation. @chelarua has updated the internals to open/close the connections when manipulating the resources. There is also fix in that should resolve your initial problem of:
Can you retry with the latest code against your RDS PostgreSQL and report your results? Tnx. |
@apparentlymart do you have an update? It seems we missed the 0.6.8 release... |
@ringods sorry I am currently a bit snowed under with other projects so I can't take a look at this right now but I'll try to get to it in the next few weeks. |
I squashed this into a single commit and made some small organizational tweaks for consistency with other providers, and then merged this as e1eef15. Thanks for all the amazing and patient work on this! 🚢 |
Any idea when this ends up in an official release?
|
Stupid question but isn't is possible to use interpolation for the provider variables? Like:
It's always asking me to input values in the console. |
My bad! Wasn't connecting databases & roles via the |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
Related to issue #3650.
Contains initial resources for:
Example usage