-
Notifications
You must be signed in to change notification settings - Fork 210
doc: Migration guide to move from API Keys (PAKs) to Service Accounts #4047
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
Changes from all commits
6673a65
abbcbc5
d861ec5
f71aec5
94d9269
a0d4586
785a98e
dc6053d
5939987
647528f
2d95fdd
74cc59f
766060a
9a96afa
e9f3c55
52d2486
dd6acfc
0fdf9ee
23927a3
8819abd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,291 @@ | ||
| --- | ||
| page_title: "Migration Guide: Programmatic API Keys (PAKs) to Service Accounts (SAs)" | ||
| --- | ||
|
|
||
| # Migration Guide: Programmatic API Keys (PAKs) to Service Accounts (SAs) | ||
|
|
||
| ## Overview | ||
|
|
||
| This guide explains how to migrate from Programmatic API Key (PAK) resources to Service Account (SA) resources managed by Terraform. | ||
|
|
||
| **Important:** The steps in this guide are for migrating Terraform-managed PAK and SA resources (e.g., `mongodbatlas_api_key`, `mongodbatlas_service_account`). If you are looking to change the Terraform provider authentication method from PAK to SA, refer to the [Provider Configuration guide](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/provider-configuration). | ||
|
|
||
| **Note:** Migration to Service Accounts is recommended but **not required**. If you are currently using API Key resources, you may continue to do so. This guide is for users who wish to adopt Service Accounts for greater security or best practices, but existing PAK configurations will continue to work and be supported. | ||
|
|
||
| ## Before You Begin | ||
|
|
||
| - **Backup your Terraform state file** before making any changes. | ||
| - **Test the process in a non-production environment** if possible. | ||
| - Managing Service Accounts with Terraform **exposes sensitive organizational secrets** in Terraform's state. We suggest following [Terraform's best practices](https://developer.hashicorp.com/terraform/language/state/sensitive-data). | ||
|
|
||
|
|
||
| --- | ||
|
|
||
| <details> | ||
| <summary><span style="font-size:1.4em; font-weight:bold;">Organization-Level Migration</span></summary> | ||
|
|
||
| ## Organization-Level API Keys to Service Accounts | ||
|
|
||
| **Objective**: Migrate from organization-level PAK resources (`mongodbatlas_api_key`, `mongodbatlas_api_key_project_assignment`, `mongodbatlas_access_list_api_key`) to organization-level Service Account resources (`mongodbatlas_service_account`, `mongodbatlas_service_account_project_assignment`, `mongodbatlas_service_account_access_list_entry`). | ||
|
|
||
| ### Resource Mapping | ||
| The following table shows the mapping between organization-level PAK resources and their Service Account equivalents: | ||
|
|
||
| | PAK Resource | Service Account Resource | Notes | | ||
manupedrozo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| |--------------|-------------------------|-------| | ||
| | `mongodbatlas_api_key` | `mongodbatlas_service_account` | API key / Service Account | | ||
| | `mongodbatlas_api_key_project_assignment` | `mongodbatlas_service_account_project_assignment` | Project assignment | | ||
| | `mongodbatlas_access_list_api_key` | `mongodbatlas_service_account_access_list_entry` | IP access list entry | | ||
|
|
||
| --- | ||
|
|
||
| ### Migration Steps | ||
|
|
||
| For complete working examples, see the [organization-level migration example](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples/migrate_pak_to_service_account/org_level). | ||
|
|
||
| ### Step 1: Initial Configuration - PAK Resources Only | ||
|
|
||
| Original configuration with PAK resources: | ||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_api_key" "this" { | ||
| org_id = var.org_id | ||
| description = "Example API Key" | ||
| role_names = ["ORG_MEMBER"] | ||
| } | ||
|
|
||
| # Project assignment for the API Key | ||
| resource "mongodbatlas_api_key_project_assignment" "this" { | ||
| project_id = var.project_id | ||
| api_key_id = mongodbatlas_api_key.this.api_key_id | ||
| roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| } | ||
|
|
||
| # IP Access List entry for the API Key | ||
| resource "mongodbatlas_access_list_api_key" "this" { | ||
| org_id = var.org_id | ||
| api_key_id = mongodbatlas_api_key.this.api_key_id | ||
| cidr_block = "192.168.1.100/32" | ||
| # Alternative: ip_address = "192.168.1.100" | ||
| } | ||
| ``` | ||
|
|
||
| ### Step 2: Intermediate State - Add Service Account Resources Alongside Existing PAK Resources | ||
|
|
||
| Add the Service Account resources to your configuration while keeping the existing PAK resources. This allows both authentication methods to work simultaneously, enabling you to test Service Accounts before removing PAKs. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the statement "allows both authentication methods to work simultaneously" is not true, both SA and PAK exist simultaneously, but are not used simultaneously.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking on the case of using SA/PAKs as the authentication method for the MongoDB Atlas Terraform Provider, but in the cases of other applications/tools, the statement can be true. Feel free to ignore the previous comment |
||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_service_account" "this" { | ||
| org_id = var.org_id | ||
| name = "example-service-account" | ||
| description = "Example Service Account" | ||
| roles = ["ORG_MEMBER"] | ||
| secret_expires_after_hours = 2160 # 90 days | ||
| } | ||
|
|
||
| resource "mongodbatlas_service_account_project_assignment" "this" { | ||
| project_id = var.project_id | ||
| client_id = mongodbatlas_service_account.this.client_id | ||
| roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| } | ||
|
|
||
| resource "mongodbatlas_service_account_access_list_entry" "this" { | ||
| org_id = var.org_id | ||
| client_id = mongodbatlas_service_account.this.client_id | ||
| cidr_block = "192.168.1.100/32" | ||
| # Alternative: ip_address = "192.168.1.100" | ||
| } | ||
|
|
||
| output "service_account_first_secret" { | ||
| description = "The secret value of the first secret created with the Service Account. Available only immediately after initial creation." | ||
| value = try(mongodbatlas_service_account.this.secrets[0].secret, null) | ||
| sensitive = true | ||
| } | ||
| ``` | ||
|
|
||
| **Apply and test:** | ||
|
|
||
| 1. Run `terraform plan` to review the changes. | ||
| 2. Run `terraform apply` to create the Service Account resources. | ||
| 3. Retrieve and securely store the `service_account_first_secret` value (**warning**: this prints the secret to your terminal): | ||
|
|
||
| ```bash | ||
| terraform output -raw service_account_first_secret | ||
| ``` | ||
|
|
||
| 4. Test your Service Account in your applications and verify that both PAK and SA authentication methods work correctly. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we explain how that would look like in the case of switching the auth method of the TF provider from PAK to SA? something similar to https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/provider-configuration#programmatic-access-key warning block where we say I say this because the guide is generic in terms of the application that uses the PAK/SA, but I think the main use case we want to enable is the TF provider authentication
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A previous iteration mentioned this. I suggested to remove it to avoid confusion and mention only "your applications". I think it makes sense for the credentials used for provider authentication in a particular configuration to be managed outside of that same configuration.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should cover the end to end case of using the new SA resource sand switching from PAK to SA as the auth method, since it's the main problem we are trying to solve by implementing these resources in TF
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am on board on including a link to the SA authentication registry page to reference how it is used but I would be careful to add it as a step here given the previous comment:
Do we know of PAK users authenticating with a PAK that is managed within the same configuration? I don't think we should be recommending this approach (can lock yourself out).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not saying to recommend the approach of using PAKs created in a configuration as the auth mechanism within the same configuration, but I would like to have in this guide the case of switching from PAK to SA as the auth mechanism of the TF provider, which is the main use case we want to enable, even if the SA/PAK is created in one configuration and used as auth in another. Hope that makes sense
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that makes sense. @filipcirtog can you mention this in the guide and include a link to the provider configuration guide with SA?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the suggestions. I have added some notes on this. Please let me know WDY. |
||
| 5. Re-run `terraform plan` to ensure you have no unexpected changes: `No changes. Your infrastructure matches the configuration.` | ||
|
|
||
| ### Step 3: Final State - Remove PAK Resources, SA Resources Only | ||
|
|
||
| Once you have verified that the Service Account works correctly, remove the PAK resources from your configuration: | ||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_service_account" "this" { | ||
| org_id = var.org_id | ||
| name = "example-service-account" | ||
| description = "Example Service Account" | ||
| roles = ["ORG_MEMBER"] | ||
| secret_expires_after_hours = 2160 # 90 days | ||
| } | ||
|
|
||
| resource "mongodbatlas_service_account_project_assignment" "this" { | ||
| project_id = var.project_id | ||
| client_id = mongodbatlas_service_account.this.client_id | ||
| roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| } | ||
|
|
||
| resource "mongodbatlas_service_account_access_list_entry" "this" { | ||
| org_id = var.org_id | ||
| client_id = mongodbatlas_service_account.this.client_id | ||
| cidr_block = "192.168.1.100/32" | ||
| } | ||
| ``` | ||
|
|
||
| 1. Run `terraform plan` to verify: | ||
| - PAK resources are planned for destruction | ||
| - Only the Service Account resources remain | ||
| - No unexpected changes | ||
|
|
||
| 2. Run `terraform apply` to finalize the migration. This will delete the PAK resources from Atlas. | ||
|
|
||
| 3. Verify that your applications and infrastructure continue to work with Service Accounts. | ||
|
|
||
| 4. Re-run `terraform plan` to ensure you have no planned changes: `No changes. Your infrastructure matches the configuration.` | ||
|
|
||
|
|
||
| </details> | ||
|
|
||
| --- | ||
|
|
||
| <details> | ||
| <summary><span style="font-size:1.4em; font-weight:bold;">Project-Level Migration</span></summary> | ||
|
|
||
| ## Project-Level API Keys to Service Accounts | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assume same comments as for Org-level steps
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated! Thank you! |
||
|
|
||
| **Objective**: Migrate from project-level PAK resources (`mongodbatlas_project_api_key`, `mongodbatlas_access_list_api_key`) to project-level Service Account resources (`mongodbatlas_project_service_account`, `mongodbatlas_project_service_account_access_list_entry`). | ||
|
|
||
| **Important:** Organization-level resources (`mongodbatlas_service_account`) are the recommended approach. Project-level resources (`mongodbatlas_project_service_account`) should only be used if you do not have organization-level permissions to manage Service Accounts. Otherwise, use the [Organization-Level Migration](#organization-level-api-keys-to-service-accounts) approach. | ||
|
|
||
| ### Resource Mapping | ||
|
|
||
| The following table shows the mapping between project-level PAK resources and their Service Account equivalents: | ||
|
|
||
| | PAK Resource | Service Account Resource | Notes | | ||
| |--------------|-------------------------|-------| | ||
| | `mongodbatlas_project_api_key` | `mongodbatlas_project_service_account` | Project-level API key / Service Account (use only if you don't have org-level permissions) | | ||
| | `mongodbatlas_access_list_api_key` | `mongodbatlas_project_service_account_access_list_entry` | IP access list entry for project-level Service Account | | ||
|
|
||
| **Important:** Organization-level resources (`mongodbatlas_service_account`) are the recommended approach. Project-level resources (`mongodbatlas_project_service_account`) should only be used if you do not have organization-level permissions to manage Service Accounts. | ||
|
|
||
| --- | ||
|
|
||
| ### Migration Steps | ||
|
|
||
| For complete working examples, see the [project-level migration example](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples/migrate_pak_to_service_account/project_level). | ||
|
|
||
| ### Step 1: Initial Configuration - PAK Resources Only | ||
|
|
||
| Original configuration with PAK resources: | ||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_project_api_key" "this" { | ||
| description = "Example Project API Key" | ||
| project_assignment { | ||
| project_id = var.project_id | ||
| role_names = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| } | ||
| } | ||
|
|
||
| # IP Access List entry for the API Key | ||
| resource "mongodbatlas_access_list_api_key" "this" { | ||
| org_id = var.org_id | ||
| api_key_id = mongodbatlas_project_api_key.this.api_key_id | ||
| cidr_block = "192.168.1.100/32" | ||
| # Alternative: ip_address = "192.168.1.100" | ||
| } | ||
| ``` | ||
|
|
||
| ### Step 2: Intermediate State - Add Service Account Resources Alongside Existing PAK Resources | ||
|
|
||
| Add the Service Account resources to your configuration while keeping the existing PAK resources. This allows both authentication methods to work simultaneously, enabling you to test Service Accounts before removing PAKs. | ||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_project_service_account" "this" { | ||
| project_id = var.project_id | ||
| name = "example-project-service-account" | ||
| description = "Example Project Service Account" | ||
| roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| secret_expires_after_hours = 2160 # 90 days | ||
| } | ||
|
|
||
| resource "mongodbatlas_project_service_account_access_list_entry" "this" { | ||
| project_id = var.project_id | ||
| client_id = mongodbatlas_project_service_account.this.client_id | ||
| cidr_block = "192.168.1.100/32" | ||
| # Alternative: ip_address = "192.168.1.100" | ||
| } | ||
|
|
||
| output "project_service_account_first_secret" { | ||
| description = "The secret value of the first secret created with the Project Service Account. Available only immediately after initial creation." | ||
| value = try(mongodbatlas_project_service_account.this.secrets[0].secret, null) | ||
| sensitive = true | ||
| } | ||
| ``` | ||
|
|
||
| **Apply and test:** | ||
|
|
||
| 1. Run `terraform plan` to review the changes. | ||
| 2. Run `terraform apply` to create the Service Account resource. | ||
| 3. Retrieve and securely store the `project_service_account_first_secret` value (**warning**: this prints the secret to your terminal): | ||
|
|
||
| ```bash | ||
| terraform output -raw project_service_account_first_secret | ||
| ``` | ||
|
|
||
| 4. Test your Service Account in your applications and verify that both PAK and SA authentication methods work correctly. | ||
| 5. Re-run `terraform plan` to ensure you have no unexpected changes: `No changes. Your infrastructure matches the configuration.` | ||
|
|
||
| ### Step 3: Final State - Remove PAK Resources, SA Resources Only | ||
|
|
||
| Once you have verified that the Service Account works correctly, remove the PAK resources from your configuration: | ||
|
|
||
| ```terraform | ||
| resource "mongodbatlas_project_service_account" "this" { | ||
| project_id = var.project_id | ||
| name = "example-project-service-account" | ||
| description = "Example Project Service Account" | ||
| roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_ONLY"] | ||
| secret_expires_after_hours = 2160 # 90 days | ||
| } | ||
|
|
||
| resource "mongodbatlas_project_service_account_access_list_entry" "this" { | ||
| project_id = var.project_id | ||
| client_id = mongodbatlas_project_service_account.this.client_id | ||
| cidr_block = "192.168.1.100/32" | ||
| } | ||
| ``` | ||
|
|
||
| 1. Run `terraform plan` to verify: | ||
| - PAK resources are planned for destruction | ||
| - Only the Service Account resources remain | ||
| - No unexpected changes | ||
|
|
||
| 2. Run `terraform apply` to finalize the migration. This will delete the PAK resource from Atlas. | ||
|
|
||
| 3. Verify that your applications and infrastructure continue to work with Service Accounts. | ||
|
|
||
| 4. Re-run `terraform plan` to ensure you have no planned changes: `No changes. Your infrastructure matches the configuration.` | ||
|
|
||
|
|
||
| </details> | ||
|
|
||
| --- | ||
|
|
||
| ## Switching the Provider Authentication Method | ||
|
|
||
| After migrating your Terraform-managed resources from PAK to SA, you may also want to switch the Terraform provider authentication method. | ||
|
|
||
| For detailed instructions on configuring Service Account authentication for the provider, see the [Provider Configuration guide](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/provider-configuration). | ||
|
|
||
| **Note:** The Service Account used for provider authentication should be created in a separate Terraform configuration or managed outside of Terraform. It is recommended to manage provider authentication credentials separately from the resources they manage to avoid potential lockout scenarios. | ||
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.
[nit] Would it make sense to use L3 headings for everything within this section? (Right sub headings are all L2)
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.
updated! thank you!