My client provisions all their accounts via Terraform using the "aws_organizations_account" "account" resource; it’s worked well for years. The accounts are defined as a variable map:
XYZ_account_map = {
email = "XYZ@foo.com"
id = "123412341234"
name = "old_name"
}
Multiple other non-account resources reference these accounts by reading their state entries.
Now we have a requirement to rename a wide range of accounts to conform to an external schema.
In theory it’s easy - we change the name in the resource, and see for example:
XYZ_account_map = {
email = ""XYZ@foo.com""
~ id = "123412341234" -> (known after apply)
~ name = "old_name" -> "new_name"
}
However …
The change in ID suggests that TF’s behaviour in this case might be an unpleasant surprise. For example, along the lines of account deletion in an organization, TF might well remove the old account from the org (rendering it unreachable without a root setup) and create a new one.
This is the sort of thing I’d rather know before trying. Could anyone respond to what the actual behaviour is in a rename case like this?
Failing the desired behaviour (just change the name), I expect we could change code and mess with state, but a rename per above would be great … if it does no harm.
wanted to check if (and how than?) you managed to rename your AWS accounts and keep TFs state in order, since I currently have the same requirement for a few of our member accounts.
Ran this in a POC and saw the same plan suggestion. Since it was a playground, I went ahead and applied the configuration, to find myself with a new AccountID …
My apologies, just now seeing this. But I have no good news.
At least so far I’ve had no success with account renaming, and am dragging around legacy names like a lead fishing weight. TF wants to recreate the account every time, and that’s a very bad outcome.
But … I have an idea I have not yet tried, based on some successful attempts in other areas. When I first created the accounts using TF I created a separate module invocation for each account create, with the module name tied to the account name.
That may be the source of the problem. And, in other contexts, the new-ish terraform state mv capability has been extremely reliable in renaming modules in state to correspond to module invocations in code.
So it just “may” be that the move may be the key. The thing I’ll try, or you can try is (assuming you have modules named for the account in legacy):
To work this out we’ll need to dig around in existing state to see how the current accounts are referred to, then move them to some basis that either does not use an account name, or alternately uses some other name.
Granted, this is just a fancy way of the messing around in state we wanted to avoid in the first place. But the terraform state mv has been sufficiently reliable that it might overcome the intrinsic cringe in state-faffing.
The aws_organizations_account Terraform resource is written to force destruction/creation when the name changes, as can be seen in the source code here:
The name passed to the resource and sent to AWS, however is distinct from the address of the resource block within your configuration, which is entirely local to Terraform. That you can change as you like, either using the terraform state mv command as you suggest, or via declarative moved blocks that you add to your configuration.
You would have to show more of the structure of your Terraform configuration, for this forum to give any more detailed suggestions.
Detailed suggestions would be most welcome @maxb, thanks!
Here’s the use case:
Account(s) created by calling the module code below as a child module and passing (among other things) an account name as shown below
We now have a need to change that account name (which is used as a key to a number of other important but irrelevant operations)
Looking at the code, we will also have a need from time to time to change the account email, which is also marked as ForceNew: true
Current behaviour is to delete and recreate the account
Desired behaviour is to simply rename whatever TF structures relate to:
** name: probably just Terraform structures. From what I can tell, the name attribute has no corresponding attribute on the AWS Side
** EMail: also need to actually change the AWS EMail of the account. If that’s not possible (using the console it requires root, not just IAM Admin), at least a way for TF to accept a manual change to email from the AWS side
Here’s the child module code example:
resource "aws_organizations_account" "generic" {
name = var.account["account_key"]
email = var.account["email"]
parent_id = var.account["orgu"]
role_name = var.admin_role
close_on_deletion = var.allow-close-on-delete
# Ignore changes to email and name. The fields are effective
# on create, and can be changed in variables.tf if needed, but
# must be manually adjusted on the AWS Console side from a root acct
# See https://github.com/hashicorp/terraform-provider-aws/issues/8947
lifecycle {
ignore_changes = [name, email]
}
}
The commented lifecycle block does not, as far as I know, create the desired behaviour.
I think to achieve your aim you’d have to manually update the name and email in AWS, possibly manually in a web browser, then manually remove (terraform state rm) and re-import (Terraform Registry) the account to have Terraform reconcile with the new details.
You’re probably right … perhaps the reason I didn’t find the name attribute on the AWS side is that it mainly (or exclusively?) shows up in the org account, not the child account. I’ll look into that.
It’s too dangerous to remove all of the state information, but a targeted removal for just the account that is changing its name could be just the thing to do. Thanks for the idea