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

Add new resource to support ALTER ROLE #211

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

bmedlock-depop
Copy link

This change will add in a new resource to the provider, ALTER_ROLE.

The resource is designed to be used where you need to alter certain attributes on a role. For example, when setting attributes associated with PGAudit, ALTER ROLE testrole SET pgaudit.log to 'all'

Closes #210

@bmedlock-depop bmedlock-depop force-pushed the PLAT-1484-add-alter-role-resource branch from 4202967 to 65eb45c Compare June 15, 2022 14:26
@robinjhector
Copy link

Sorry to bump this, but is this good to merge and release @cyrilgdn ?

@ALX-TH
Copy link

ALX-TH commented Aug 2, 2022

same question to @cyrilgdn , any chance to have such feature ?
thanks.

@hunkeelin
Copy link

@robinjhector the CI tests are failing.

@jenrik
Copy link

jenrik commented Aug 11, 2022

@bmedlock-depop The test are failing because the test setup run them both as a superuser role and a less privileged roles. This can be fixed by adding the following line to the top of the test that require superuser access: testSuperuserPreCheck(t)

https://github.com/depop/terraform-provider-postgresql/blob/PLAT-1484-add-alter-role-resource/postgresql/utils_test.go#L32

@bmedlock-depop
Copy link
Author

@jenrik Thanks for the help! I should have time this week to fix this.

@bmedlock-depop
Copy link
Author

@cyrilgdn Tests should now be passing.

Thanks for your patience, everyone!

@ALX-TH
Copy link

ALX-TH commented Sep 16, 2022

@cyrilgdn can you please take a look on this request ? ;)

@bmedlock-depop
Copy link
Author

@cyrilgdn I've just fixed the conflicts on the branch. Everything should be good. Please could you take look?

@jbg
Copy link

jbg commented Mar 15, 2023

This proposed resource is inconsistent with the declarative model of Terraform. A resource is a thing, not an operation. The resource is the role, and this resource already exists (postgresql_role). ALTER ROLE is something the provider runs when that resource is changed.

The right way to implement this would be to add configuration parameter support to postgresql_role. You would then import the role to the Terraform state, if it's not already there, and then add/modify the configuration parameter, which the provider would apply by running ALTER ROLE.

In the Terraform configuration, that would look something like:

resource "postgresql_role" "foo" {
  name = "foo"

  parameter {
    name = "pgaudit.log"
    value = "all"
  }
}

@rowanmoul
Copy link

This proposed resource is inconsistent with the declarative model of Terraform. A resource is a thing, not an operation. The resource is the role, and this resource already exists (postgresql_role). ALTER ROLE is something the provider runs when that resource is changed.

I completely agree, however, sometimes the role was created by a different terraform provider that does not provide the ability to make the necessary changes. See #234
You could of course argue that those other providers should be fixed to give more control over the role that is created, but they are at the mercy of the underlying cloud platforms, and those are unlikely to be responsive to changes in any sort of timely manner. An ALTER ROLE resource (or a flag on the postgresql_role resource that indicates the role already exists) would allow people to use native terraform resources to work around this, rather than using provisioners or manually run scripts.

@sscheible
Copy link

sscheible commented Jul 17, 2023

This proposed resource is inconsistent with the declarative model of Terraform. A resource is a thing, not an operation. The resource is the role, and this resource already exists (postgresql_role). ALTER ROLE is something the provider runs when that resource is changed.

I completely agree, however, sometimes the role was created by a different terraform provider that does not provide the ability to make the necessary changes. See #234 You could of course argue that those other providers should be fixed to give more control over the role that is created, but they are at the mercy of the underlying cloud platforms, and those are unlikely to be responsive to changes in any sort of timely manner. An ALTER ROLE resource (or a flag on the postgresql_role resource that indicates the role already exists) would allow people to use native terraform resources to work around this, rather than using provisioners or manually run scripts.

Having the same with google_sql_user resources which I need to ALTER. A more declarative resource approach could be to restrict the ALTER ROLE to configuration parameters and call the resource "postgresql_role_configuration_parameter", the thing to be created being the configuration parameter on the role. This essentially leads to #305

Edit in response to @jbg: google_sql_user is explicitly created, but falls in the same 'at mercy' category as mentioned by @rowanmoul

@jbg
Copy link

jbg commented Jul 17, 2023

I completely agree, however, sometimes the role was created by a different terraform provider that does not provide the ability to make the necessary changes. See #234 You could of course argue that those other providers should be fixed to give more control over the role that is created, but they are at the mercy of the underlying cloud platforms, and those are unlikely to be responsive to changes in any sort of timely manner. An ALTER ROLE resource (or a flag on the postgresql_role resource that indicates the role already exists) would allow people to use native terraform resources to work around this, rather than using provisioners or manually run scripts.

Generally you'd deal with this by importing the implicitly-created resource after the other provider has created it, after which you can deal with it declaratively like normal. This has been improved recently with the addition of import blocks, though there is still work to do there.

@ktham
Copy link

ktham commented Jul 27, 2023

This proposed resource is inconsistent with the declarative model of Terraform. A resource is a thing, not an operation. The resource is the role, and this resource already exists (postgresql_role).

I understand the concern and agree in principle, but I don't see an inconsistency with this proposed PR, perhaps the naming of the resource can be better. In fact, if you look at the parameters for CREATE ROLE, you will not find session config parameters there, it's a separate query to get these added (or removed) using a "SET <session_config_param> = <session_config_value>" statement with an ALTER ROLE query after the PG role has been created to get these session config params added for the role, so I think this can be reasonably managed independently as a separate Terraform resource.

This is very similar to how we have aws_security_group resources and at the same time, we have aws_security_group_rule. Or aws_s3_bucket and s3_bucket_ownership_controls (which used to be contained inside the aws_s3_bucket resource in versions prior to 4.x of the AWS provider, but are now separate Terraform resources).

@bmedlock-depop My suggestion would be to call this resource postgresql_role_configuration_parameter to make this clearer rather than the present name of postgresql_alter_role.

I think this PR is the simpler and more flexible solution relative to the other proposal of adding this in-line to the postgresql_role resource as this would handle the use-case of PG roles that are created and managed outside of our control (e.g. like those created for us by the cloud vendor such as AWS, Azure, etc...), and thus, managed by a Terraform resource of a separate provider. The suggestion to import it seems hacky and it's unclear how reliable this would be, to have two providers manage the same resource, I can see potentially this bringing in more problems than it attempts to solve. The solution here seems much simpler and doesn't conflict with Terraform's declarative model and so I would vote for this PR (after the resource rename to postgresql_role_configuration_parameter)

@bhoriuchi
Copy link

For special permissions like CREATEROLE, CREATEDB, etc the following

https://github.com/cyrilgdn/terraform-provider-postgresql/pull/211/files#diff-485fa37a4d8bc2c9c3bf2bb5991a782b2e2135653bf55684d098534742e85cecR170

doesnt work. Would it be possible to get some special case queries for these. i.e.

func createAlterRoleQuery(d *schema.ResourceData) string {
	alterRole, _ := d.Get("role_name").(string)
	alterParameterKey, _ := d.Get("parameter_key").(string)
	alterParameterValue, _ := d.Get("parameter_value").(string)

	query := fmt.Sprintf(
		"ALTER ROLE %s SET %s TO %s",
		pq.QuoteIdentifier(alterRole),
		pq.QuoteIdentifier(alterParameterKey),
		pq.QuoteIdentifier(alterParameterValue),
	)

	switch key := strings.ToUpper(alterParameterKey); key {
	case "SUPERUSER",
		"CREATEDB",
		"CREATEROLE",
		"INHERIT",
		"LOGIN",
		"REPLICATION",
		"BYPASSRLS":
		query = fmt.Sprintf("ALTER ROLE %s %s", pq.QuoteIdentifier(alterRole), key)
	}

	return query
}

func createResetAlterRoleQuery(d *schema.ResourceData) string {
	alterRole, _ := d.Get("role_name").(string)
	alterParameterKey, _ := d.Get("parameter_key").(string)

	query := fmt.Sprintf(
		"ALTER ROLE %s RESET %s",
		pq.QuoteIdentifier(alterRole),
		pq.QuoteIdentifier(alterParameterKey),
	)

	switch key := strings.ToUpper(alterParameterKey); key {
	case "SUPERUSER",
		"CREATEDB",
		"CREATEROLE",
		"INHERIT",
		"LOGIN",
		"REPLICATION",
		"BYPASSRLS":
		query = fmt.Sprintf("ALTER ROLE %s NO%s", pq.QuoteIdentifier(alterRole), key)
	}

	return query
}

achellouche added a commit to doctolib/terraform-provider-postgresql that referenced this pull request Dec 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for ALTER ROLE xxx SET yyy = zzz;
10 participants