From 1459a03a18a0e95fa7fa73d5e825760953a7e41b Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Mon, 25 Aug 2025 13:53:02 +0200 Subject: [PATCH 01/30] initial doc --- README.md | 136 +++++--------- docs/command_adv2v2.md | 224 +++++++++++++++++++++++ docs/command_clu2adv.md | 101 +++++++++++ docs/guide_adv2v2_dynamic_block.md | 278 +++++++++++++++++++++++++++++ 4 files changed, 651 insertions(+), 88 deletions(-) create mode 100644 docs/command_adv2v2.md create mode 100644 docs/command_clu2adv.md create mode 100644 docs/guide_adv2v2_dynamic_block.md diff --git a/README.md b/README.md index 4e6fef0..d03965b 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,33 @@ This repository contains the Atlas CLI plugin for [Terraform's MongoDB Atlas Provider](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs). -It has the following commands to help with your Terraform configurations: -- **clusterToAdvancedCluster**: Convert a `mongodbatlas_cluster` Terraform configuration to `mongodbatlas_advanced_cluster` (preview provider 2.0.0). +## Available Commands + +The plugin provides the following commands to help with your Terraform configurations: + +### 1. clusterToAdvancedCluster (clu2adv) +Convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` format for Provider 2.0.0. + +**Quick Start:** +```bash +atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf +# or using alias +atlas tf clu2adv -f in.tf -o out.tf +``` + +[📖 Full Documentation](./docs/command_clu2adv.md) | [Dynamic Blocks Guide](./docs/guide_clu2adv_dynamic_block.md) + +### 2. advancedClusterToV2 (adv2v2) +Convert legacy `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 format with simplified structure. + +**Quick Start:** +```bash +atlas terraform advancedClusterToV2 --file in.tf --output out.tf +# or using alias +atlas tf adv2v2 -f in.tf -o out.tf +``` + +[📖 Full Documentation](./docs/command_adv2v2.md) | [Dynamic Blocks Guide](./docs/guide_adv2v2_dynamic_block.md) ## Installation @@ -26,101 +51,36 @@ If you want to see the list of installed plugins or check if this plugin is inst atlas plugin list ``` -## Convert mongodbatlas_cluster to mongodbatlas_advanced_cluster (preview provider 2.0.0) - -### Usage - -You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). +## Provider 2.0.0 Preview -**Note**: In order to use the **Preview for MongoDB Atlas Provider 2.0.0** of `mongodbatlas_advanced_cluster`, you need to set the environment variable `MONGODB_ATLAS_PREVIEW_PROVIDER_V2_ADVANCED_CLUSTER` to `true`. - -If you want to convert a Terraform configuration from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster`, use the following command: +**Note**: To use the **Preview for MongoDB Atlas Provider 2.0.0**, set the environment variable: ```bash -atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf +export MONGODB_ATLAS_PREVIEW_PROVIDER_V2_ADVANCED_CLUSTER=true ``` -you can also use shorter aliases, e.g.: -```bash -atlas tf clu2adv -f in.tf -o out.tf -``` - -If you want to include the `moved blocks` in the output file, use the `--includeMoved` or the `-m` flag. - -If you want to overwrite the output file if it exists, or even use the same output file as the input file, use the `--replaceOutput` or the `-r` flag. +## Quick Migration Guide -You can use the `--watch` or the `-w` flag to keep the plugin running and watching for changes in the input file. You can have input and output files open in an editor and see easily how changes to the input file affect the output file. +### From mongodbatlas_cluster to mongodbatlas_advanced_cluster +1. Use `clu2adv` to convert your existing cluster configurations +2. Review the converted output, especially dynamic blocks +3. Test in a development environment +4. Apply to production -You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/clu2adv) some examples of input files (suffix .in.tf) and the corresponding output files (suffix .out.tf). +[Learn more →](./docs/command_clu2adv.md) -### Dynamic blocks +### From Legacy to Provider 2.0.0 Format +1. Use `adv2v2` to update your advanced cluster configurations +2. Verify the flattened `replication_specs` structure +3. Check that `region_configs` is now `config` +4. Test thoroughly before production deployment -`dynamic` blocks are used to generate multiple nested blocks based on a set of values. -Given the different ways of using dynamic blocks, we recommend reviewing the output and making sure it fits your needs. - -#### Dynamic blocks in tags and labels - -You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that `for_each` has an expression which is evaluated to a `map` of strings. -You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: -```hcl -tags { - key = "environment" - value = var.environment -} -dynamic "tags" { - for_each = var.tags - content { - key = tags.key - value = replace(tags.value, "/", "_") - } -} -``` - -#### Dynamic blocks in regions_config - -You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` or `set` of objects. See this [guide](./docs/guide_clu2adv_dynamic_block.md) to learn more about some limitations. -This is an example of how to use dynamic blocks in `regions_config`: -```hcl -replication_specs { - num_shards = var.replication_specs.num_shards - zone_name = var.replication_specs.zone_name # only needed if you're using zones - dynamic "regions_config" { - for_each = var.replication_specs.regions_config - content { - priority = regions_config.value.priority - region_name = regions_config.value.region_name - electable_nodes = regions_config.value.electable_nodes - read_only_nodes = regions_config.value.read_only_nodes - } - } -} -``` - -#### Dynamic blocks in replication_specs - -You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. See this [guide](./docs/guide_clu2adv_dynamic_block.md) to learn more about some limitations. -This is an example of how to use dynamic blocks in `replication_specs`: -```hcl -dynamic "replication_specs" { - for_each = var.replication_specs - content { - num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name # only needed if you're using zones - dynamic "regions_config" { - for_each = replication_specs.value.regions_config - content { - electable_nodes = regions_config.value.electable_nodes - priority = regions_config.value.priority - read_only_nodes = regions_config.value.read_only_nodes - region_name = regions_config.value.region_name - } - } - } -} -``` +[Learn more →](./docs/command_adv2v2.md) -### Limitations +## Examples -- `dynamic` blocks are supported with some [limitations](./docs/guide_clu2adv_dynamic_block.md). +Find example conversions in the test data directories: +- [clu2adv examples](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/clu2adv) +- [adv2v2 examples](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2) ## Feedback @@ -132,4 +92,4 @@ See our [CONTRIBUTING.md](CONTRIBUTING.md) guide. ## License -MongoDB Atlas CLI is released under the Apache 2.0 license. See [LICENSE.md](LICENSE.md) +MongoDB Atlas CLI is released under the Apache 2.0 license. See [LICENSE.md](LICENSE.md) \ No newline at end of file diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md new file mode 100644 index 0000000..2850d1d --- /dev/null +++ b/docs/command_adv2v2.md @@ -0,0 +1,224 @@ +# Convert mongodbatlas_advanced_cluster to Provider 2.0.0 Format + +This command helps you migrate `mongodbatlas_advanced_cluster` configurations from the legacy SDKv2 format to the new Provider 2.0.0 format. + +## Background + +MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatlas_advanced_cluster` resources. The main changes include: +- Simplified `replication_specs` structure +- `region_configs` is now `config` (as an array) +- Cleaner handling of `num_shards` +- Better support for dynamic blocks + +## Usage + +To convert a Terraform configuration from the legacy `mongodbatlas_advanced_cluster` format to the Provider 2.0.0 format, use the following command: + +```bash +atlas terraform advancedClusterToV2 --file in.tf --output out.tf +``` + +You can also use shorter aliases: +```bash +atlas tf adv2v2 -f in.tf -o out.tf +``` + +### Command Options + +- `--file` or `-f`: Input file path containing the legacy `mongodbatlas_advanced_cluster` configuration +- `--output` or `-o`: Output file path for the converted Provider 2.0.0 configuration +- `--replaceOutput` or `-r`: Overwrite the output file if it exists +- `--watch` or `-w`: Keep the plugin running and watching for changes in the input file + +## Examples + +You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2) examples of input files (suffix .in.tf) and the corresponding output files (suffix .out.tf). + +### Basic Conversion Example + +**Input (Legacy Format):** +```hcl +resource "mongodbatlas_advanced_cluster" "example" { + project_id = var.project_id + name = "example-cluster" + cluster_type = "REPLICASET" + + replication_specs { + num_shards = 1 + region_configs { + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs { + instance_size = "M10" + node_count = 3 + } + } + } +} +``` + +**Output (Provider 2.0.0 Format):** +```hcl +resource "mongodbatlas_advanced_cluster" "example" { + project_id = var.project_id + name = "example-cluster" + cluster_type = "REPLICASET" + + replication_specs = [{ + config = [{ + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = "M10" + node_count = 3 + } + }] + }] +} +``` + +## Dynamic Blocks + +The converter intelligently handles `dynamic` blocks, transforming them to work with the new Provider 2.0.0 structure. + +### Dynamic replication_specs + +When you have dynamic `replication_specs` blocks, the converter will: +1. Flatten the structure appropriately +2. Transform `region_configs` to `config` +3. Handle `num_shards` correctly + +**Input:** +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name + dynamic "region_configs" { + for_each = replication_specs.value.region_configs + content { + region_name = region_configs.value.region_name + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + electable_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.node_count + } + } + } + } +} +``` + +**Output:** +```hcl +replication_specs = flatten([ + for spec in var.replication_specs : [ + for i in range(spec.num_shards) : { + zone_name = spec.zone_name + config = [ + for region in spec.region_configs : { + region_name = region.region_name + priority = region.priority + provider_name = region.provider_name + electable_specs = { + instance_size = region.instance_size + node_count = region.node_count + } + } + ] + } + ] +]) +``` + +### Dynamic tags and labels + +Dynamic blocks for `tags` and `labels` are preserved but converted to use the new object syntax: + +**Input:** +```hcl +dynamic "tags" { + for_each = var.tags + content { + key = tags.key + value = tags.value + } +} +``` + +**Output:** +```hcl +tags = { + for tag in var.tags : tag.key => tag.value +} +``` + +## Sharded Clusters + +For sharded clusters (where `num_shards > 1`), the converter correctly expands the replication specs: + +**Input:** +```hcl +replication_specs { + num_shards = 3 + region_configs { + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs { + instance_size = "M10" + node_count = 3 + } + } +} +``` + +**Output:** +```hcl +replication_specs = [ + { + config = [{ + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = "M10" + node_count = 3 + } + }] + }, + { + config = [{ + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = "M10" + node_count = 3 + } + }] + }, + { + config = [{ + region_name = "US_EAST_1" + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = "M10" + node_count = 3 + } + }] + } +] +``` + +## Limitations + +- The converter requires valid HCL syntax in the input file +- Complex expressions in dynamic blocks may require manual review +- Custom functions or complex conditionals in `for_each` expressions are preserved but should be tested +- See the [dynamic blocks guide](./guide_adv2v2_dynamic_block.md) for more details on dynamic block handling \ No newline at end of file diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md new file mode 100644 index 0000000..7667425 --- /dev/null +++ b/docs/command_clu2adv.md @@ -0,0 +1,101 @@ +# Convert mongodbatlas_cluster to mongodbatlas_advanced_cluster + +This command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` (preview provider 2.0.0). + +## Usage + +You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). + +**Note**: In order to use the **Preview for MongoDB Atlas Provider 2.0.0** of `mongodbatlas_advanced_cluster`, you need to set the environment variable `MONGODB_ATLAS_PREVIEW_PROVIDER_V2_ADVANCED_CLUSTER` to `true`. + +If you want to convert a Terraform configuration from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster`, use the following command: +```bash +atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf +``` + +you can also use shorter aliases, e.g.: +```bash +atlas tf clu2adv -f in.tf -o out.tf +``` + +### Command Options + +- `--file` or `-f`: Input file path containing the `mongodbatlas_cluster` configuration +- `--output` or `-o`: Output file path for the converted `mongodbatlas_advanced_cluster` configuration +- `--includeMoved` or `-m`: Include the `moved blocks` in the output file +- `--replaceOutput` or `-r`: Overwrite the output file if it exists, or even use the same output file as the input file +- `--watch` or `-w`: Keep the plugin running and watching for changes in the input file + +## Examples + +You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/clu2adv) some examples of input files (suffix .in.tf) and the corresponding output files (suffix .out.tf). + +## Dynamic Blocks + +`dynamic` blocks are used to generate multiple nested blocks based on a set of values. +Given the different ways of using dynamic blocks, we recommend reviewing the output and making sure it fits your needs. + +### Dynamic blocks in tags and labels + +You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that `for_each` has an expression which is evaluated to a `map` of strings. +You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: +```hcl +tags { + key = "environment" + value = var.environment +} +dynamic "tags" { + for_each = var.tags + content { + key = tags.key + value = replace(tags.value, "/", "_") + } +} +``` + +### Dynamic blocks in regions_config + +You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` or `set` of objects. See the [dynamic blocks guide](./guide_clu2adv_dynamic_block.md) to learn more about some limitations. +This is an example of how to use dynamic blocks in `regions_config`: +```hcl +replication_specs { + num_shards = var.replication_specs.num_shards + zone_name = var.replication_specs.zone_name # only needed if you're using zones + dynamic "regions_config" { + for_each = var.replication_specs.regions_config + content { + priority = regions_config.value.priority + region_name = regions_config.value.region_name + electable_nodes = regions_config.value.electable_nodes + read_only_nodes = regions_config.value.read_only_nodes + } + } +} +``` + +### Dynamic blocks in replication_specs + +You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. See the [dynamic blocks guide](./guide_clu2adv_dynamic_block.md) to learn more about some limitations. +This is an example of how to use dynamic blocks in `replication_specs`: +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name # only needed if you're using zones + dynamic "regions_config" { + for_each = replication_specs.value.regions_config + content { + electable_nodes = regions_config.value.electable_nodes + priority = regions_config.value.priority + read_only_nodes = regions_config.value.read_only_nodes + region_name = regions_config.value.region_name + } + } + } +} +``` + +## Limitations + +- `dynamic` blocks are supported with some [limitations](./guide_clu2adv_dynamic_block.md). \ No newline at end of file diff --git a/docs/guide_adv2v2_dynamic_block.md b/docs/guide_adv2v2_dynamic_block.md new file mode 100644 index 0000000..127a3d0 --- /dev/null +++ b/docs/guide_adv2v2_dynamic_block.md @@ -0,0 +1,278 @@ +# Guide to Dynamic Blocks in advancedClusterToV2 Conversion + +The plugin command to convert `mongodbatlas_advanced_cluster` resources from legacy SDKv2 format to Provider 2.0.0 format handles `dynamic` blocks intelligently. This guide explains how dynamic blocks are transformed and any limitations you should be aware of. + +If you need to use the plugin for use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). + +## Dynamic Blocks in replication_specs + +When using dynamic blocks for `replication_specs`, the converter will transform them into a flattened structure that properly handles the Provider 2.0.0 format. + +### Basic Dynamic replication_specs + +**Input (Legacy Format):** +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name + region_configs { + region_name = replication_specs.value.region_name + priority = 7 + provider_name = "AWS" + electable_specs { + instance_size = replication_specs.value.instance_size + node_count = 3 + } + } + } +} +``` + +**Output (Provider 2.0.0 Format):** +```hcl +replication_specs = flatten([ + for spec in var.replication_specs : [ + for i in range(spec.num_shards) : { + zone_name = spec.zone_name + config = [{ + region_name = spec.region_name + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = spec.instance_size + node_count = 3 + } + }] + } + ] +]) +``` + +### Nested Dynamic Blocks (replication_specs with dynamic region_configs) + +When you have nested dynamic blocks (dynamic `replication_specs` containing dynamic `region_configs`), the converter handles both levels: + +**Input:** +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name + dynamic "region_configs" { + for_each = replication_specs.value.regions + content { + region_name = region_configs.value.region_name + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + electable_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.node_count + } + } + } + } +} +``` + +**Output:** +```hcl +replication_specs = flatten([ + for spec in var.replication_specs : [ + for i in range(spec.num_shards) : { + zone_name = spec.zone_name + config = [ + for region in spec.regions : { + region_name = region.region_name + priority = region.priority + provider_name = region.provider_name + electable_specs = { + instance_size = region.instance_size + node_count = region.node_count + } + } + ] + } + ] +]) +``` + +## Dynamic Blocks in region_configs + +Dynamic blocks within `region_configs` (now `config` in Provider 2.0.0) are transformed to use list comprehensions: + +**Input:** +```hcl +replication_specs { + num_shards = 1 + dynamic "region_configs" { + for_each = var.regions + content { + region_name = region_configs.value.region_name + priority = region_configs.value.priority + provider_name = "AWS" + electable_specs { + instance_size = region_configs.value.instance_size + node_count = 3 + } + } + } +} +``` + +**Output:** +```hcl +replication_specs = [{ + config = [ + for region in var.regions : { + region_name = region.region_name + priority = region.priority + provider_name = "AWS" + electable_specs = { + instance_size = region.instance_size + node_count = 3 + } + } + ] +}] +``` + +## Dynamic Blocks in tags and labels + +Dynamic blocks for `tags` and `labels` are converted from block syntax to object syntax: + +### Tags + +**Input:** +```hcl +dynamic "tags" { + for_each = var.tags + content { + key = tags.key + value = tags.value + } +} +``` + +**Output:** +```hcl +tags = { + for tag in var.tags : tag.key => tag.value +} +``` + +### Labels + +**Input:** +```hcl +dynamic "labels" { + for_each = var.labels + content { + key = labels.key + value = labels.value + } +} +``` + +**Output:** +```hcl +labels = { + for label in var.labels : label.key => label.value +} +``` + +## Handling num_shards with Dynamic Blocks + +The converter properly handles `num_shards` expansion when using dynamic blocks: + +1. **For literal num_shards values**: The converter expands the replication spec for each shard +2. **For variable num_shards values**: The converter uses `range()` function to handle the expansion dynamically + +**Example with variable num_shards:** +```hcl +# Input +dynamic "replication_specs" { + for_each = var.specs + content { + num_shards = replication_specs.value.shards + # ... config + } +} + +# Output +replication_specs = flatten([ + for spec in var.specs : [ + for i in range(spec.shards) : { + # ... config + } + ] +]) +``` + +## Mixed Static and Dynamic Blocks + +If you have both static and dynamic blocks for `replication_specs` or `region_configs`, the converter handles them separately: + +**Input:** +```hcl +replication_specs { + num_shards = 1 + region_configs { + region_name = "US_EAST_1" + # ... config + } +} + +dynamic "replication_specs" { + for_each = var.additional_specs + content { + # ... config + } +} +``` + +**Output:** +```hcl +replication_specs = concat( + [{ + config = [{ + region_name = "US_EAST_1" + # ... config + }] + }], + flatten([ + for spec in var.additional_specs : [ + # ... transformed dynamic content + ] + ]) +) +``` + +## Limitations and Considerations + +1. **Complex for_each expressions**: While the converter preserves complex expressions in `for_each`, you should verify that they still work as expected in the new format. + +2. **Custom functions**: If you use custom functions or complex conditionals within dynamic blocks, these are preserved but should be tested after conversion. + +3. **Variable references**: The converter updates variable references appropriately (e.g., `replication_specs.value` to `spec`), but complex nested references should be reviewed. + +4. **Block ordering**: The Provider 2.0.0 format may handle block ordering differently. Ensure that any dependencies on block order are maintained. + +## Best Practices + +1. **Review the output**: Always review the converted configuration to ensure it matches your intentions. + +2. **Test incrementally**: Test the converted configuration in a development environment before applying to production. + +3. **Simplify when possible**: If the converter produces complex nested expressions, consider simplifying them manually for better readability. + +4. **Use terraform plan**: Always run `terraform plan` after conversion to verify that the changes are as expected. + +## Examples + +You can find more examples of dynamic block conversions in the [test data directory](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2), particularly: +- `dynamic_replication_specs.in.tf` / `.out.tf` +- `dynamic_region_configs.in.tf` / `.out.tf` +- `dynamic_tags_labels.in.tf` / `.out.tf` \ No newline at end of file From da42d2819e279759c3da1e52c1c475be44d39bba Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Mon, 25 Aug 2025 15:52:18 +0200 Subject: [PATCH 02/30] remove guide_clu2adv_dynamic_block --- docs/command_clu2adv.md | 97 +++++++++++++++++++++++++++- docs/guide_clu2adv_dynamic_block.md | 98 ----------------------------- 2 files changed, 95 insertions(+), 100 deletions(-) delete mode 100644 docs/guide_clu2adv_dynamic_block.md diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 7667425..b969927 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -96,6 +96,99 @@ dynamic "replication_specs" { } ``` -## Limitations +### Limitations -- `dynamic` blocks are supported with some [limitations](./guide_clu2adv_dynamic_block.md). \ No newline at end of file +If you need to use the plugin for `dynamic` block use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). + +#### Dynamic block and individual blocks in the same resource + +Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat) if you're using a list or [setunion](https://developer.hashicorp.com/terraform/language/functions/setunion) for sets. + +Let's see an example with `regions_config`, it is the same for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `region_config` with a read-only node. +```hcl +variable "replication_specs" { + type = object({ + num_shards = number + regions_config = list(object({ + region_name = string + electable_nodes = number + priority = number + read_only_nodes = number + })) + }) +} + +resource "mongodbatlas_cluster" "this" { + project_id = var.project_id + name = var.cluster_name + cluster_type = var.cluster_type + provider_name = var.provider_name + provider_instance_size_name = var.provider_instance_size_name + replication_specs { + num_shards = var.replication_specs.num_shards + dynamic "regions_config" { + for_each = var.replication_specs.regions_config + content { + region_name = regions_config.value.region_name + electable_nodes = regions_config.value.electable_nodes + priority = regions_config.value.priority + read_only_nodes = regions_config.value.read_only_nodes + } + } + regions_config { # individual region + region_name = "US_EAST_1" + read_only_nodes = 1 + } + } +} +``` + +We modify the configuration file to create an intermediate `local` variable to merge the `regions_config` variable elements and the additional `region_config`: +```hcl +variable "replication_specs" { + type = object({ + num_shards = number + regions_config = list(object({ + region_name = string + electable_nodes = number + priority = number + read_only_nodes = number + })) + }) +} + +locals { + regions_config_all = concat( + var.replication_specs.regions_config, + [ + { + region_name = "US_EAST_1" + electable_nodes = 0 + priority = 0 + read_only_nodes = 1 + }, + ] + ) +} + +resource "mongodbatlas_cluster" "this" { + project_id = var.project_id + name = var.cluster_name + cluster_type = var.cluster_type + provider_name = var.provider_name + provider_instance_size_name = var.provider_instance_size_name + replication_specs { + num_shards = var.replication_specs.num_shards + dynamic "regions_config" { + for_each = local.regions_config_all # changed to use the local variable + content { + region_name = regions_config.value.region_name + electable_nodes = regions_config.value.electable_nodes + priority = regions_config.value.priority + read_only_nodes = regions_config.value.read_only_nodes + } + } + } +} +``` +This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it is supported by the plugin. diff --git a/docs/guide_clu2adv_dynamic_block.md b/docs/guide_clu2adv_dynamic_block.md deleted file mode 100644 index 667039c..0000000 --- a/docs/guide_clu2adv_dynamic_block.md +++ /dev/null @@ -1,98 +0,0 @@ -# Guide to handle dynamic block limitations in regions_config and replication_specs - -The plugin command to convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` supports `dynamic` blocks for `regions_config` and `replication_specs`. However, there are some limitations when using `dynamic` blocks in these fields. This guide explains how to handle these limitations. - -If you need to use the plugin for use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). - -## Dynamic block and individual blocks in the same resource - -Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat) if you're using a list or [setunion](https://developer.hashicorp.com/terraform/language/functions/setunion) for sets. - -Let's see an example with `regions_config`, it is the same for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `region_config` with a read-only node. -```hcl -variable "replication_specs" { - type = object({ - num_shards = number - regions_config = list(object({ - region_name = string - electable_nodes = number - priority = number - read_only_nodes = number - })) - }) -} - -resource "mongodbatlas_cluster" "this" { - project_id = var.project_id - name = var.cluster_name - cluster_type = var.cluster_type - provider_name = var.provider_name - provider_instance_size_name = var.provider_instance_size_name - replication_specs { - num_shards = var.replication_specs.num_shards - dynamic "regions_config" { - for_each = var.replication_specs.regions_config - content { - region_name = regions_config.value.region_name - electable_nodes = regions_config.value.electable_nodes - priority = regions_config.value.priority - read_only_nodes = regions_config.value.read_only_nodes - } - } - regions_config { # individual region - region_name = "US_EAST_1" - read_only_nodes = 1 - } - } -} -``` - -We modify the configuration file to create an intermediate `local` variable to merge the `regions_config` variable elements and the additional `region_config`: -```hcl -variable "replication_specs" { - type = object({ - num_shards = number - regions_config = list(object({ - region_name = string - electable_nodes = number - priority = number - read_only_nodes = number - })) - }) -} - -locals { - regions_config_all = concat( - var.replication_specs.regions_config, - [ - { - region_name = "US_EAST_1" - electable_nodes = 0 - priority = 0 - read_only_nodes = 1 - }, - ] - ) -} - -resource "mongodbatlas_cluster" "this" { - project_id = var.project_id - name = var.cluster_name - cluster_type = var.cluster_type - provider_name = var.provider_name - provider_instance_size_name = var.provider_instance_size_name - replication_specs { - num_shards = var.replication_specs.num_shards - dynamic "regions_config" { - for_each = local.regions_config_all # changed to use the local variable - content { - region_name = regions_config.value.region_name - electable_nodes = regions_config.value.electable_nodes - priority = regions_config.value.priority - read_only_nodes = regions_config.value.read_only_nodes - } - } - } -} -``` -This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it is supported by the plugin. From e27d5a440f7b6e809be77adcf70ec9797a69d335 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Mon, 25 Aug 2025 16:01:18 +0200 Subject: [PATCH 03/30] move info in file guide_adv2v2_dynamic_block.md to command_adv2v2.md --- README.md | 2 +- docs/command_adv2v2.md | 261 ++++++++++++++++++++++++++- docs/guide_adv2v2_dynamic_block.md | 278 ----------------------------- 3 files changed, 259 insertions(+), 282 deletions(-) delete mode 100644 docs/guide_adv2v2_dynamic_block.md diff --git a/README.md b/README.md index d03965b..cc907c0 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ atlas terraform advancedClusterToV2 --file in.tf --output out.tf atlas tf adv2v2 -f in.tf -o out.tf ``` -[📖 Full Documentation](./docs/command_adv2v2.md) | [Dynamic Blocks Guide](./docs/guide_adv2v2_dynamic_block.md) +[📖 Full Documentation](./docs/command_adv2v2.md) ## Installation diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 2850d1d..b0f6121 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -216,9 +216,264 @@ replication_specs = [ ] ``` +## Dynamic Block Handling + +The converter intelligently handles `dynamic` blocks, transforming them to work with the new Provider 2.0.0 structure. + +### Dynamic Blocks in replication_specs + +When using dynamic blocks for `replication_specs`, the converter transforms them into a flattened structure: + +#### Basic Dynamic replication_specs + +**Input (Legacy Format):** +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name + region_configs { + region_name = replication_specs.value.region_name + priority = 7 + provider_name = "AWS" + electable_specs { + instance_size = replication_specs.value.instance_size + node_count = 3 + } + } + } +} +``` + +**Output (Provider 2.0.0 Format):** +```hcl +replication_specs = flatten([ + for spec in var.replication_specs : [ + for i in range(spec.num_shards) : { + zone_name = spec.zone_name + config = [{ + region_name = spec.region_name + priority = 7 + provider_name = "AWS" + electable_specs = { + instance_size = spec.instance_size + node_count = 3 + } + }] + } + ] +]) +``` + +#### Nested Dynamic Blocks + +When you have nested dynamic blocks (dynamic `replication_specs` containing dynamic `region_configs`), the converter handles both levels: + +**Input:** +```hcl +dynamic "replication_specs" { + for_each = var.replication_specs + content { + num_shards = replication_specs.value.num_shards + zone_name = replication_specs.value.zone_name + dynamic "region_configs" { + for_each = replication_specs.value.regions + content { + region_name = region_configs.value.region_name + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + electable_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.node_count + } + } + } + } +} +``` + +**Output:** +```hcl +replication_specs = flatten([ + for spec in var.replication_specs : [ + for i in range(spec.num_shards) : { + zone_name = spec.zone_name + config = [ + for region in spec.regions : { + region_name = region.region_name + priority = region.priority + provider_name = region.provider_name + electable_specs = { + instance_size = region.instance_size + node_count = region.node_count + } + } + ] + } + ] +]) +``` + +### Dynamic Blocks in region_configs + +Dynamic blocks within `region_configs` (now `config` in Provider 2.0.0) are transformed to use list comprehensions: + +**Input:** +```hcl +replication_specs { + num_shards = 1 + dynamic "region_configs" { + for_each = var.regions + content { + region_name = region_configs.value.region_name + priority = region_configs.value.priority + provider_name = "AWS" + electable_specs { + instance_size = region_configs.value.instance_size + node_count = 3 + } + } + } +} +``` + +**Output:** +```hcl +replication_specs = [{ + config = [ + for region in var.regions : { + region_name = region.region_name + priority = region.priority + provider_name = "AWS" + electable_specs = { + instance_size = region.instance_size + node_count = 3 + } + } + ] +}] +``` + +### Dynamic Blocks in tags and labels + +Dynamic blocks for `tags` and `labels` are converted from block syntax to object syntax: + +**Tags Input:** +```hcl +dynamic "tags" { + for_each = var.tags + content { + key = tags.key + value = tags.value + } +} +``` + +**Tags Output:** +```hcl +tags = { + for tag in var.tags : tag.key => tag.value +} +``` + +### Handling num_shards with Dynamic Blocks + +The converter properly handles `num_shards` expansion: + +1. **For literal num_shards values**: The converter expands the replication spec for each shard +2. **For variable num_shards values**: The converter uses `range()` function to handle the expansion dynamically + +**Example with variable num_shards:** +```hcl +# Input +dynamic "replication_specs" { + for_each = var.specs + content { + num_shards = replication_specs.value.shards + # ... config + } +} + +# Output +replication_specs = flatten([ + for spec in var.specs : [ + for i in range(spec.shards) : { + # ... config + } + ] +]) +``` + +### Mixed Static and Dynamic Blocks + +If you have both static and dynamic blocks for `replication_specs` or `region_configs`, the converter handles them separately: + +**Input:** +```hcl +replication_specs { + num_shards = 1 + region_configs { + region_name = "US_EAST_1" + # ... config + } +} + +dynamic "replication_specs" { + for_each = var.additional_specs + content { + # ... config + } +} +``` + +**Output:** +```hcl +replication_specs = concat( + [{ + config = [{ + region_name = "US_EAST_1" + # ... config + }] + }], + flatten([ + for spec in var.additional_specs : [ + # ... transformed dynamic content + ] + ]) +) +``` + ## Limitations +### Dynamic Block Limitations + +1. **Complex for_each expressions**: While the converter preserves complex expressions in `for_each`, they should be verified after conversion to ensure they work with the new structure. + +2. **Custom functions in dynamic blocks**: If you use custom functions or complex conditionals within dynamic blocks, these are preserved but must be tested thoroughly. + +3. **Variable references transformation**: The converter updates variable references (e.g., `replication_specs.value` to `spec`), but complex nested references should be reviewed. + +4. **Block ordering**: The Provider 2.0.0 format may handle block ordering differently. Ensure any dependencies on block order are maintained. + +### General Limitations + - The converter requires valid HCL syntax in the input file -- Complex expressions in dynamic blocks may require manual review -- Custom functions or complex conditionals in `for_each` expressions are preserved but should be tested -- See the [dynamic blocks guide](./guide_adv2v2_dynamic_block.md) for more details on dynamic block handling \ No newline at end of file +- Manual review is recommended for complex configurations +- Always run `terraform plan` after conversion to verify the changes + +If you encounter use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). + +## Best Practices + +1. **Review the output**: Always review the converted configuration to ensure it matches your intentions. +2. **Test incrementally**: Test the converted configuration in a development environment before applying to production. +3. **Simplify when possible**: If the converter produces complex nested expressions, consider simplifying them manually for better readability. +4. **Use terraform plan**: Always run `terraform plan` after conversion to verify that the changes are as expected. + +## More Examples + +You can find more examples of dynamic block conversions in the [test data directory](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2), particularly: +- `dynamic_replication_specs.in.tf` / `.out.tf` +- `dynamic_region_configs.in.tf` / `.out.tf` +- `dynamic_tags_labels.in.tf` / `.out.tf` \ No newline at end of file diff --git a/docs/guide_adv2v2_dynamic_block.md b/docs/guide_adv2v2_dynamic_block.md deleted file mode 100644 index 127a3d0..0000000 --- a/docs/guide_adv2v2_dynamic_block.md +++ /dev/null @@ -1,278 +0,0 @@ -# Guide to Dynamic Blocks in advancedClusterToV2 Conversion - -The plugin command to convert `mongodbatlas_advanced_cluster` resources from legacy SDKv2 format to Provider 2.0.0 format handles `dynamic` blocks intelligently. This guide explains how dynamic blocks are transformed and any limitations you should be aware of. - -If you need to use the plugin for use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). - -## Dynamic Blocks in replication_specs - -When using dynamic blocks for `replication_specs`, the converter will transform them into a flattened structure that properly handles the Provider 2.0.0 format. - -### Basic Dynamic replication_specs - -**Input (Legacy Format):** -```hcl -dynamic "replication_specs" { - for_each = var.replication_specs - content { - num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name - region_configs { - region_name = replication_specs.value.region_name - priority = 7 - provider_name = "AWS" - electable_specs { - instance_size = replication_specs.value.instance_size - node_count = 3 - } - } - } -} -``` - -**Output (Provider 2.0.0 Format):** -```hcl -replication_specs = flatten([ - for spec in var.replication_specs : [ - for i in range(spec.num_shards) : { - zone_name = spec.zone_name - config = [{ - region_name = spec.region_name - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = spec.instance_size - node_count = 3 - } - }] - } - ] -]) -``` - -### Nested Dynamic Blocks (replication_specs with dynamic region_configs) - -When you have nested dynamic blocks (dynamic `replication_specs` containing dynamic `region_configs`), the converter handles both levels: - -**Input:** -```hcl -dynamic "replication_specs" { - for_each = var.replication_specs - content { - num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name - dynamic "region_configs" { - for_each = replication_specs.value.regions - content { - region_name = region_configs.value.region_name - priority = region_configs.value.priority - provider_name = region_configs.value.provider_name - electable_specs { - instance_size = region_configs.value.instance_size - node_count = region_configs.value.node_count - } - } - } - } -} -``` - -**Output:** -```hcl -replication_specs = flatten([ - for spec in var.replication_specs : [ - for i in range(spec.num_shards) : { - zone_name = spec.zone_name - config = [ - for region in spec.regions : { - region_name = region.region_name - priority = region.priority - provider_name = region.provider_name - electable_specs = { - instance_size = region.instance_size - node_count = region.node_count - } - } - ] - } - ] -]) -``` - -## Dynamic Blocks in region_configs - -Dynamic blocks within `region_configs` (now `config` in Provider 2.0.0) are transformed to use list comprehensions: - -**Input:** -```hcl -replication_specs { - num_shards = 1 - dynamic "region_configs" { - for_each = var.regions - content { - region_name = region_configs.value.region_name - priority = region_configs.value.priority - provider_name = "AWS" - electable_specs { - instance_size = region_configs.value.instance_size - node_count = 3 - } - } - } -} -``` - -**Output:** -```hcl -replication_specs = [{ - config = [ - for region in var.regions : { - region_name = region.region_name - priority = region.priority - provider_name = "AWS" - electable_specs = { - instance_size = region.instance_size - node_count = 3 - } - } - ] -}] -``` - -## Dynamic Blocks in tags and labels - -Dynamic blocks for `tags` and `labels` are converted from block syntax to object syntax: - -### Tags - -**Input:** -```hcl -dynamic "tags" { - for_each = var.tags - content { - key = tags.key - value = tags.value - } -} -``` - -**Output:** -```hcl -tags = { - for tag in var.tags : tag.key => tag.value -} -``` - -### Labels - -**Input:** -```hcl -dynamic "labels" { - for_each = var.labels - content { - key = labels.key - value = labels.value - } -} -``` - -**Output:** -```hcl -labels = { - for label in var.labels : label.key => label.value -} -``` - -## Handling num_shards with Dynamic Blocks - -The converter properly handles `num_shards` expansion when using dynamic blocks: - -1. **For literal num_shards values**: The converter expands the replication spec for each shard -2. **For variable num_shards values**: The converter uses `range()` function to handle the expansion dynamically - -**Example with variable num_shards:** -```hcl -# Input -dynamic "replication_specs" { - for_each = var.specs - content { - num_shards = replication_specs.value.shards - # ... config - } -} - -# Output -replication_specs = flatten([ - for spec in var.specs : [ - for i in range(spec.shards) : { - # ... config - } - ] -]) -``` - -## Mixed Static and Dynamic Blocks - -If you have both static and dynamic blocks for `replication_specs` or `region_configs`, the converter handles them separately: - -**Input:** -```hcl -replication_specs { - num_shards = 1 - region_configs { - region_name = "US_EAST_1" - # ... config - } -} - -dynamic "replication_specs" { - for_each = var.additional_specs - content { - # ... config - } -} -``` - -**Output:** -```hcl -replication_specs = concat( - [{ - config = [{ - region_name = "US_EAST_1" - # ... config - }] - }], - flatten([ - for spec in var.additional_specs : [ - # ... transformed dynamic content - ] - ]) -) -``` - -## Limitations and Considerations - -1. **Complex for_each expressions**: While the converter preserves complex expressions in `for_each`, you should verify that they still work as expected in the new format. - -2. **Custom functions**: If you use custom functions or complex conditionals within dynamic blocks, these are preserved but should be tested after conversion. - -3. **Variable references**: The converter updates variable references appropriately (e.g., `replication_specs.value` to `spec`), but complex nested references should be reviewed. - -4. **Block ordering**: The Provider 2.0.0 format may handle block ordering differently. Ensure that any dependencies on block order are maintained. - -## Best Practices - -1. **Review the output**: Always review the converted configuration to ensure it matches your intentions. - -2. **Test incrementally**: Test the converted configuration in a development environment before applying to production. - -3. **Simplify when possible**: If the converter produces complex nested expressions, consider simplifying them manually for better readability. - -4. **Use terraform plan**: Always run `terraform plan` after conversion to verify that the changes are as expected. - -## Examples - -You can find more examples of dynamic block conversions in the [test data directory](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2), particularly: -- `dynamic_replication_specs.in.tf` / `.out.tf` -- `dynamic_region_configs.in.tf` / `.out.tf` -- `dynamic_tags_labels.in.tf` / `.out.tf` \ No newline at end of file From 0ec0ed71383df2b6f6f72a785186a766a36a2f3b Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:05:28 +0200 Subject: [PATCH 04/30] update clu2adv doc --- README.md | 39 ++++----------------------------------- docs/command_adv2v2.md | 14 +++++++------- docs/command_clu2adv.md | 16 ++++++++-------- 3 files changed, 19 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index cc907c0..e2c3146 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This repository contains the Atlas CLI plugin for [Terraform's MongoDB Atlas Pro The plugin provides the following commands to help with your Terraform configurations: ### 1. clusterToAdvancedCluster (clu2adv) -Convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` format for Provider 2.0.0. +Convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema.0.0. **Quick Start:** ```bash @@ -18,10 +18,10 @@ atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf atlas tf clu2adv -f in.tf -o out.tf ``` -[📖 Full Documentation](./docs/command_clu2adv.md) | [Dynamic Blocks Guide](./docs/guide_clu2adv_dynamic_block.md) +[📖 Full Documentation](./docs/command_clu2adv.md) | [🔄 Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide) ### 2. advancedClusterToV2 (adv2v2) -Convert legacy `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 format with simplified structure. +Convert previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema with simplified structure. **Quick Start:** ```bash @@ -51,37 +51,6 @@ If you want to see the list of installed plugins or check if this plugin is inst atlas plugin list ``` -## Provider 2.0.0 Preview - -**Note**: To use the **Preview for MongoDB Atlas Provider 2.0.0**, set the environment variable: -```bash -export MONGODB_ATLAS_PREVIEW_PROVIDER_V2_ADVANCED_CLUSTER=true -``` - -## Quick Migration Guide - -### From mongodbatlas_cluster to mongodbatlas_advanced_cluster -1. Use `clu2adv` to convert your existing cluster configurations -2. Review the converted output, especially dynamic blocks -3. Test in a development environment -4. Apply to production - -[Learn more →](./docs/command_clu2adv.md) - -### From Legacy to Provider 2.0.0 Format -1. Use `adv2v2` to update your advanced cluster configurations -2. Verify the flattened `replication_specs` structure -3. Check that `region_configs` is now `config` -4. Test thoroughly before production deployment - -[Learn more →](./docs/command_adv2v2.md) - -## Examples - -Find example conversions in the test data directories: -- [clu2adv examples](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/clu2adv) -- [adv2v2 examples](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2) - ## Feedback If you find any issues or have any suggestions, please open an [issue](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues) in this repository. @@ -92,4 +61,4 @@ See our [CONTRIBUTING.md](CONTRIBUTING.md) guide. ## License -MongoDB Atlas CLI is released under the Apache 2.0 license. See [LICENSE.md](LICENSE.md) \ No newline at end of file +MongoDB Atlas CLI is released under the Apache 2.0 license. See [LICENSE.md](LICENSE.md) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index b0f6121..05bf062 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -1,6 +1,6 @@ -# Convert mongodbatlas_advanced_cluster to Provider 2.0.0 Format +# Convert mongodbatlas_advanced_cluster to Provider 2.0.0 schema -This command helps you migrate `mongodbatlas_advanced_cluster` configurations from the legacy SDKv2 format to the new Provider 2.0.0 format. + advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. ## Background @@ -12,7 +12,7 @@ MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatl ## Usage -To convert a Terraform configuration from the legacy `mongodbatlas_advanced_cluster` format to the Provider 2.0.0 format, use the following command: +To convert a Terraform configuration from the previous `mongodbatlas_advanced_cluster` schema to the Provider 2.0.0 schema, use the following command: ```bash atlas terraform advancedClusterToV2 --file in.tf --output out.tf @@ -25,9 +25,9 @@ atlas tf adv2v2 -f in.tf -o out.tf ### Command Options -- `--file` or `-f`: Input file path containing the legacy `mongodbatlas_advanced_cluster` configuration +- `--file` or `-f`: Input file path containing the `mongodbatlas_advanced_cluster` configuration - `--output` or `-o`: Output file path for the converted Provider 2.0.0 configuration -- `--replaceOutput` or `-r`: Overwrite the output file if it exists +- `--replaceOutput` or `-r`: Overwrite the output file if it exists, or even use the same output file as the input file - `--watch` or `-w`: Keep the plugin running and watching for changes in the input file ## Examples @@ -454,7 +454,7 @@ replication_specs = concat( 3. **Variable references transformation**: The converter updates variable references (e.g., `replication_specs.value` to `spec`), but complex nested references should be reviewed. -4. **Block ordering**: The Provider 2.0.0 format may handle block ordering differently. Ensure any dependencies on block order are maintained. +4. **Block ordering**: The Provider 2.0.0 schema may handle block ordering differently. Ensure any dependencies on block order are maintained. ### General Limitations @@ -476,4 +476,4 @@ If you encounter use cases not yet supported, please send us [feedback](https:// You can find more examples of dynamic block conversions in the [test data directory](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2), particularly: - `dynamic_replication_specs.in.tf` / `.out.tf` - `dynamic_region_configs.in.tf` / `.out.tf` -- `dynamic_tags_labels.in.tf` / `.out.tf` \ No newline at end of file +- `dynamic_tags_labels.in.tf` / `.out.tf` diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index b969927..f489d87 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -1,13 +1,11 @@ # Convert mongodbatlas_cluster to mongodbatlas_advanced_cluster -This command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` (preview provider 2.0.0). +clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. ## Usage You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). -**Note**: In order to use the **Preview for MongoDB Atlas Provider 2.0.0** of `mongodbatlas_advanced_cluster`, you need to set the environment variable `MONGODB_ATLAS_PREVIEW_PROVIDER_V2_ADVANCED_CLUSTER` to `true`. - If you want to convert a Terraform configuration from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster`, use the following command: ```bash atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf @@ -22,9 +20,9 @@ atlas tf clu2adv -f in.tf -o out.tf - `--file` or `-f`: Input file path containing the `mongodbatlas_cluster` configuration - `--output` or `-o`: Output file path for the converted `mongodbatlas_advanced_cluster` configuration -- `--includeMoved` or `-m`: Include the `moved blocks` in the output file - `--replaceOutput` or `-r`: Overwrite the output file if it exists, or even use the same output file as the input file - `--watch` or `-w`: Keep the plugin running and watching for changes in the input file +- `--includeMoved` or `-m`: Include the `moved blocks` in the output file ## Examples @@ -55,7 +53,8 @@ dynamic "tags" { ### Dynamic blocks in regions_config -You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` or `set` of objects. See the [dynamic blocks guide](./guide_clu2adv_dynamic_block.md) to learn more about some limitations. +You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. + This is an example of how to use dynamic blocks in `regions_config`: ```hcl replication_specs { @@ -75,7 +74,8 @@ replication_specs { ### Dynamic blocks in replication_specs -You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. See the [dynamic blocks guide](./guide_clu2adv_dynamic_block.md) to learn more about some limitations. +You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. + This is an example of how to use dynamic blocks in `replication_specs`: ```hcl dynamic "replication_specs" { @@ -102,9 +102,9 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Dynamic block and individual blocks in the same resource -Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat) if you're using a list or [setunion](https://developer.hashicorp.com/terraform/language/functions/setunion) for sets. +Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat). -Let's see an example with `regions_config`, it is the same for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `region_config` with a read-only node. +Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl variable "replication_specs" { type = object({ From 88653b0d607c964e3ba9aee8c6a4611d2c66d43f Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:55:54 +0200 Subject: [PATCH 05/30] update adv2v2 doc --- docs/command_adv2v2.md | 521 ++++++++++------------------------------- 1 file changed, 127 insertions(+), 394 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 05bf062..1bc7e24 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -2,13 +2,7 @@ advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. -## Background - -MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatlas_advanced_cluster` resources. The main changes include: -- Simplified `replication_specs` structure -- `region_configs` is now `config` (as an array) -- Cleaner handling of `num_shards` -- Better support for dynamic blocks +MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatlas_advanced_cluster` resources. The main changes include the use of nested attributes instead of blocks and deletion of deprecated attributes like `disk_size_gb` at root level or `num_shards`. ## Usage @@ -34,446 +28,185 @@ atlas tf adv2v2 -f in.tf -o out.tf You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2) examples of input files (suffix .in.tf) and the corresponding output files (suffix .out.tf). -### Basic Conversion Example - -**Input (Legacy Format):** -```hcl -resource "mongodbatlas_advanced_cluster" "example" { - project_id = var.project_id - name = "example-cluster" - cluster_type = "REPLICASET" - - replication_specs { - num_shards = 1 - region_configs { - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs { - instance_size = "M10" - node_count = 3 - } - } - } -} -``` - -**Output (Provider 2.0.0 Format):** -```hcl -resource "mongodbatlas_advanced_cluster" "example" { - project_id = var.project_id - name = "example-cluster" - cluster_type = "REPLICASET" - - replication_specs = [{ - config = [{ - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = "M10" - node_count = 3 - } - }] - }] -} -``` - ## Dynamic Blocks -The converter intelligently handles `dynamic` blocks, transforming them to work with the new Provider 2.0.0 structure. - -### Dynamic replication_specs +`dynamic` blocks are used to generate multiple nested blocks based on a set of values. +Given the different ways of using dynamic blocks, we recommend reviewing the output and making sure it fits your needs. -When you have dynamic `replication_specs` blocks, the converter will: -1. Flatten the structure appropriately -2. Transform `region_configs` to `config` -3. Handle `num_shards` correctly +### Dynamic blocks in tags and labels -**Input:** +You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that `for_each` has an expression which is evaluated to a `map` of strings. +You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: ```hcl -dynamic "replication_specs" { - for_each = var.replication_specs - content { - num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name - dynamic "region_configs" { - for_each = replication_specs.value.region_configs - content { - region_name = region_configs.value.region_name - priority = region_configs.value.priority - provider_name = region_configs.value.provider_name - electable_specs { - instance_size = region_configs.value.instance_size - node_count = region_configs.value.node_count - } - } - } - } +tags { + key = "environment" + value = var.environment } -``` - -**Output:** -```hcl -replication_specs = flatten([ - for spec in var.replication_specs : [ - for i in range(spec.num_shards) : { - zone_name = spec.zone_name - config = [ - for region in spec.region_configs : { - region_name = region.region_name - priority = region.priority - provider_name = region.provider_name - electable_specs = { - instance_size = region.instance_size - node_count = region.node_count - } - } - ] - } - ] -]) -``` - -### Dynamic tags and labels - -Dynamic blocks for `tags` and `labels` are preserved but converted to use the new object syntax: - -**Input:** -```hcl dynamic "tags" { - for_each = var.tags - content { - key = tags.key - value = tags.value - } + for_each = var.tags + content { + key = tags.key + value = replace(tags.value, "/", "_") + } } ``` -**Output:** -```hcl -tags = { - for tag in var.tags : tag.key => tag.value -} -``` +### Dynamic blocks in regions_config -## Sharded Clusters +You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. -For sharded clusters (where `num_shards > 1`), the converter correctly expands the replication specs: - -**Input:** +This is an example of how to use dynamic blocks in `region_configs`: ```hcl replication_specs { - num_shards = 3 - region_configs { - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs { - instance_size = "M10" - node_count = 3 - } - } -} -``` - -**Output:** -```hcl -replication_specs = [ - { - config = [{ - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = "M10" - node_count = 3 - } - }] - }, - { - config = [{ - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = "M10" - node_count = 3 - } - }] - }, - { - config = [{ - region_name = "US_EAST_1" - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = "M10" - node_count = 3 - } - }] - } -] -``` - -## Dynamic Block Handling - -The converter intelligently handles `dynamic` blocks, transforming them to work with the new Provider 2.0.0 structure. - -### Dynamic Blocks in replication_specs - -When using dynamic blocks for `replication_specs`, the converter transforms them into a flattened structure: - -#### Basic Dynamic replication_specs - -**Input (Legacy Format):** -```hcl -dynamic "replication_specs" { - for_each = var.replication_specs - content { - num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name - region_configs { - region_name = replication_specs.value.region_name - priority = 7 - provider_name = "AWS" + num_shards = var.replication_specs.num_shards + zone_name = var.replication_specs.zone_name # only needed if you're using zones + dynamic "region_configs" { + for_each = var.replication_specs.region_configs + content { + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + region_name = region_configs.value.region_name electable_specs { - instance_size = replication_specs.value.instance_size - node_count = 3 + instance_size = region_configs.value.instance_size + node_count = region_configs.value.electable_node_count } + # read_only_specs, analytics_specs, auto_scaling and analytics_auto_scaling can also be defined } } } ``` -**Output (Provider 2.0.0 Format):** -```hcl -replication_specs = flatten([ - for spec in var.replication_specs : [ - for i in range(spec.num_shards) : { - zone_name = spec.zone_name - config = [{ - region_name = spec.region_name - priority = 7 - provider_name = "AWS" - electable_specs = { - instance_size = spec.instance_size - node_count = 3 - } - }] - } - ] -]) -``` +### Dynamic blocks in replication_specs -#### Nested Dynamic Blocks +You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. -When you have nested dynamic blocks (dynamic `replication_specs` containing dynamic `region_configs`), the converter handles both levels: - -**Input:** +This is an example of how to use dynamic blocks in `replication_specs`: ```hcl dynamic "replication_specs" { for_each = var.replication_specs content { num_shards = replication_specs.value.num_shards - zone_name = replication_specs.value.zone_name + zone_name = replication_specs.value.zone_name # only needed if you're using zones dynamic "region_configs" { - for_each = replication_specs.value.regions - content { - region_name = region_configs.value.region_name - priority = region_configs.value.priority - provider_name = region_configs.value.provider_name - electable_specs { - instance_size = region_configs.value.instance_size - node_count = region_configs.value.node_count - } + for_each = replication_specs.value.region_configs + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + region_name = region_configs.value.region_name + electable_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.electable_node_count } + # read_only_specs, analytics_specs, auto_scaling and analytics_auto_scaling can also be defined } } } ``` -**Output:** -```hcl -replication_specs = flatten([ - for spec in var.replication_specs : [ - for i in range(spec.num_shards) : { - zone_name = spec.zone_name - config = [ - for region in spec.regions : { - region_name = region.region_name - priority = region.priority - provider_name = region.provider_name - electable_specs = { - instance_size = region.instance_size - node_count = region.node_count - } - } - ] - } - ] -]) -``` +### Limitations -### Dynamic Blocks in region_configs +If you need to use the plugin for `dynamic` block use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). -Dynamic blocks within `region_configs` (now `config` in Provider 2.0.0) are transformed to use list comprehensions: +#### Dynamic block and individual blocks in the same resource -**Input:** +Dynamic block and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat). + +Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl -replication_specs { - num_shards = 1 - dynamic "region_configs" { - for_each = var.regions - content { - region_name = region_configs.value.region_name - priority = region_configs.value.priority - provider_name = "AWS" +variable "replication_specs" { + type = object({ + num_shards = number + region_configs = list(object({ + priority = number + provider_name = string + region_name = string + instance_size = string + electable_node_count = number + read_only_node_count = number + })) + }) +} + +resource "mongodbatlas_advanced_cluster" "this" { + project_id = var.project_id + name = var.cluster_name + cluster_type = var.cluster_type + replication_specs { + num_shards = var.replication_specs.num_shards + dynamic "region_configs" { + for_each = var.replication_specs.region_configs + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + region_name = region_configs.value.region_name electable_specs { instance_size = region_configs.value.instance_size - node_count = 3 + node_count = region_configs.value.electable_node_count } - } - } -} -``` - -**Output:** -```hcl -replication_specs = [{ - config = [ - for region in var.regions : { - region_name = region.region_name - priority = region.priority - provider_name = "AWS" - electable_specs = { - instance_size = region.instance_size - node_count = 3 + read_only_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.read_only_node_count } } - ] -}] -``` - -### Dynamic Blocks in tags and labels - -Dynamic blocks for `tags` and `labels` are converted from block syntax to object syntax: - -**Tags Input:** -```hcl -dynamic "tags" { - for_each = var.tags - content { - key = tags.key - value = tags.value + region_configs { # individual region + instance_size = "US_EAST_1" + read_only_nodes = 1 + } } } ``` -**Tags Output:** -```hcl -tags = { - for tag in var.tags : tag.key => tag.value +We modify the configuration file to create an intermediate `local` variable to merge the `region_configs` variable elements and the additional `region_config`: +```hcl +variable "replication_specs" { + type = object({ + num_shards = number + region_configs = list(object({ + priority = number + provider_name = string + region_name = string + instance_size = string + electable_node_count = number + read_only_node_count = number + })) + }) } -``` - -### Handling num_shards with Dynamic Blocks - -The converter properly handles `num_shards` expansion: -1. **For literal num_shards values**: The converter expands the replication spec for each shard -2. **For variable num_shards values**: The converter uses `range()` function to handle the expansion dynamically - -**Example with variable num_shards:** -```hcl -# Input -dynamic "replication_specs" { - for_each = var.specs - content { - num_shards = replication_specs.value.shards - # ... config - } +locals { + region_configs_all = concat( + var.replication_specs.region_configs, + [ + { + priority = 0 + provide_name = var.provider_aname + region_name = "US_EAST_1" + instance_size = var.instance_size + electable_node_count = 0 + read_only_node_count = 1 + }, + ] + ) } -# Output -replication_specs = flatten([ - for spec in var.specs : [ - for i in range(spec.shards) : { - # ... config +resource "mongodbatlas_advanced_cluster" "this" { + project_id = var.project_id + name = var.cluster_name + cluster_type = var.cluster_type + replication_specs { + num_shards = var.replication_specs.num_shards + dynamic "regions_config" { + for_each = local.regions_config_all # changed to use the local variable + priority = region_configs.value.priority + provider_name = region_configs.value.provider_name + region_name = region_configs.value.region_name + electable_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.electable_node_count + } + read_only_specs { + instance_size = region_configs.value.instance_size + node_count = region_configs.value.read_only_node_count + } } - ] -]) -``` - -### Mixed Static and Dynamic Blocks - -If you have both static and dynamic blocks for `replication_specs` or `region_configs`, the converter handles them separately: - -**Input:** -```hcl -replication_specs { - num_shards = 1 - region_configs { - region_name = "US_EAST_1" - # ... config - } -} - -dynamic "replication_specs" { - for_each = var.additional_specs - content { - # ... config } } ``` - -**Output:** -```hcl -replication_specs = concat( - [{ - config = [{ - region_name = "US_EAST_1" - # ... config - }] - }], - flatten([ - for spec in var.additional_specs : [ - # ... transformed dynamic content - ] - ]) -) -``` - -## Limitations - -### Dynamic Block Limitations - -1. **Complex for_each expressions**: While the converter preserves complex expressions in `for_each`, they should be verified after conversion to ensure they work with the new structure. - -2. **Custom functions in dynamic blocks**: If you use custom functions or complex conditionals within dynamic blocks, these are preserved but must be tested thoroughly. - -3. **Variable references transformation**: The converter updates variable references (e.g., `replication_specs.value` to `spec`), but complex nested references should be reviewed. - -4. **Block ordering**: The Provider 2.0.0 schema may handle block ordering differently. Ensure any dependencies on block order are maintained. - -### General Limitations - -- The converter requires valid HCL syntax in the input file -- Manual review is recommended for complex configurations -- Always run `terraform plan` after conversion to verify the changes - -If you encounter use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). - -## Best Practices - -1. **Review the output**: Always review the converted configuration to ensure it matches your intentions. -2. **Test incrementally**: Test the converted configuration in a development environment before applying to production. -3. **Simplify when possible**: If the converter produces complex nested expressions, consider simplifying them manually for better readability. -4. **Use terraform plan**: Always run `terraform plan` after conversion to verify that the changes are as expected. - -## More Examples - -You can find more examples of dynamic block conversions in the [test data directory](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/tree/main/internal/convert/testdata/adv2v2), particularly: -- `dynamic_replication_specs.in.tf` / `.out.tf` -- `dynamic_region_configs.in.tf` / `.out.tf` -- `dynamic_tags_labels.in.tf` / `.out.tf` +This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it is supported by the plugin. From 0c349b1d06b52db18ea49aa9ec126874811abd46 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:02:40 +0200 Subject: [PATCH 06/30] typos --- README.md | 2 +- docs/command_adv2v2.md | 12 ++++++------ docs/command_clu2adv.md | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e2c3146..5809f8e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This repository contains the Atlas CLI plugin for [Terraform's MongoDB Atlas Pro The plugin provides the following commands to help with your Terraform configurations: ### 1. clusterToAdvancedCluster (clu2adv) -Convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema.0.0. +Convert `mongodbatlas_cluster` resources to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. **Quick Start:** ```bash diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 1bc7e24..d36abbb 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -51,9 +51,9 @@ dynamic "tags" { } ``` -### Dynamic blocks in regions_config +### Dynamic blocks in region_configs -You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. +You can use `dynamic` blocks for `region_configs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. This is an example of how to use dynamic blocks in `region_configs`: ```hcl @@ -108,9 +108,9 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Dynamic block and individual blocks in the same resource -Dynamic block and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat). +Dynamic block and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. +Let's see an example with `region_configs`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl variable "replication_specs" { type = object({ @@ -192,8 +192,8 @@ resource "mongodbatlas_advanced_cluster" "this" { cluster_type = var.cluster_type replication_specs { num_shards = var.replication_specs.num_shards - dynamic "regions_config" { - for_each = local.regions_config_all # changed to use the local variable + dynamic "region_configs" { + for_each = local.region_configs_all # changed to use the local variable priority = region_configs.value.priority provider_name = region_configs.value.provider_name region_name = region_configs.value.region_name diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index f489d87..5b90c24 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -2,10 +2,10 @@ clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. -## Usage - You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). +## Usage + If you want to convert a Terraform configuration from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster`, use the following command: ```bash atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf @@ -102,7 +102,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Dynamic block and individual blocks in the same resource -Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable to add the individual block information to the variable you're using in the `for_each` expression, using [concat](https://developer.hashicorp.com/terraform/language/functions/concat). +Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression,. Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl @@ -143,7 +143,7 @@ resource "mongodbatlas_cluster" "this" { } ``` -We modify the configuration file to create an intermediate `local` variable to merge the `regions_config` variable elements and the additional `region_config`: +We modify the configuration file to create an intermediate `local` variable to merge the `regions_config` variable elements and the additional `regions_config`: ```hcl variable "replication_specs" { type = object({ From 1a508f30fdee131291d6f25dddc321e5a3c9c3f0 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:09:05 +0200 Subject: [PATCH 07/30] fix individual region --- docs/command_adv2v2.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index d36abbb..ad38fe0 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -147,8 +147,13 @@ resource "mongodbatlas_advanced_cluster" "this" { } } region_configs { # individual region - instance_size = "US_EAST_1" - read_only_nodes = 1 + priority = 0 + provider_name = "AWS" + region_name = "US_EAST_1" + read_only_specs { + instance_size = var.instance_size + node_count = 1 + } } } } @@ -176,7 +181,7 @@ locals { [ { priority = 0 - provide_name = var.provider_aname + provide_name = "AWS" region_name = "US_EAST_1" instance_size = var.instance_size electable_node_count = 0 From 2eb09585285e2ed3b2ab7f291a65817989c70f1d Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:11:00 +0200 Subject: [PATCH 08/30] typo --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index ad38fe0..6103556 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -159,7 +159,7 @@ resource "mongodbatlas_advanced_cluster" "this" { } ``` -We modify the configuration file to create an intermediate `local` variable to merge the `region_configs` variable elements and the additional `region_config`: +We modify the configuration file to create an intermediate `local` variable to merge the `region_configs` variable elements and the additional `region_configs`: ```hcl variable "replication_specs" { type = object({ From 52c69e8fba240bf23c4699b6e6533a5c7d2bd993 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:46:08 +0200 Subject: [PATCH 09/30] Update docs/command_adv2v2.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 6103556..c442426 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -181,7 +181,7 @@ locals { [ { priority = 0 - provide_name = "AWS" + provider_name = "AWS" region_name = "US_EAST_1" instance_size = var.instance_size electable_node_count = 0 From 646a4e240f585052b50c1f6a1c99f275b5325931 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 12:00:53 +0200 Subject: [PATCH 10/30] installation first --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 5809f8e..dfde07a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,25 @@ This repository contains the Atlas CLI plugin for [Terraform's MongoDB Atlas Provider](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs). +## Installation + +Install the [Atlas CLI](https://github.com/mongodb/mongodb-atlas-cli) if you haven't done it yet. + +Install the plugin by running: +```bash +atlas plugin install github.com/mongodb-labs/atlas-cli-plugin-terraform +``` + +If you have it installed and want to update it to the latest version, run: +```bash +atlas plugin update mongodb-labs/atlas-cli-plugin-terraform +``` + +If you want to see the list of installed plugins or check if this plugin is installed, run: +```bash +atlas plugin list +``` + ## Available Commands The plugin provides the following commands to help with your Terraform configurations: @@ -32,25 +51,6 @@ atlas tf adv2v2 -f in.tf -o out.tf [📖 Full Documentation](./docs/command_adv2v2.md) -## Installation - -Install the [Atlas CLI](https://github.com/mongodb/mongodb-atlas-cli) if you haven't done it yet. - -Install the plugin by running: -```bash -atlas plugin install github.com/mongodb-labs/atlas-cli-plugin-terraform -``` - -If you have it installed and want to update it to the latest version, run: -```bash -atlas plugin update mongodb-labs/atlas-cli-plugin-terraform -``` - -If you want to see the list of installed plugins or check if this plugin is installed, run: -```bash -atlas plugin list -``` - ## Feedback If you find any issues or have any suggestions, please open an [issue](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues) in this repository. From 23593a55d4fe30bdea61a950e22d320d883d5b3b Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:05:53 +0200 Subject: [PATCH 11/30] Update docs/command_clu2adv.md Co-authored-by: Agustin Bettati --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 5b90c24..e65d6bd 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -102,7 +102,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Dynamic block and individual blocks in the same resource -Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression,. +Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl From 3a64a89f62fbdbd8485acac42e85bf083aef6027 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:10:37 +0200 Subject: [PATCH 12/30] change dynamic block section name --- docs/command_adv2v2.md | 2 +- docs/command_clu2adv.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index c442426..485afe2 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -106,7 +106,7 @@ dynamic "replication_specs" { If you need to use the plugin for `dynamic` block use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). -#### Dynamic block and individual blocks in the same resource +#### Combination of blocks with dynamic and inline expressions Dynamic block and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index e65d6bd..fcca87f 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -100,7 +100,7 @@ dynamic "replication_specs" { If you need to use the plugin for `dynamic` block use cases not yet supported, please send us [feedback](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/issues). -#### Dynamic block and individual blocks in the same resource +#### Combination of blocks with dynamic and inline expressions Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. From 3ed0cde0091b92327dfba841ef653881c9b58237 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Tue, 26 Aug 2025 15:30:50 +0200 Subject: [PATCH 13/30] add doc clarification about underlaying resources not being changed --- docs/command_adv2v2.md | 2 ++ docs/command_clu2adv.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 485afe2..ee9ef06 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -2,6 +2,8 @@ advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. +This revised file migrates the Terraform configurations and state to the latest version and does not modify the resources deployed in MongoDB Atlas. + MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatlas_advanced_cluster` resources. The main changes include the use of nested attributes instead of blocks and deletion of deprecated attributes like `disk_size_gb` at root level or `num_shards`. ## Usage diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index fcca87f..7118b69 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -2,6 +2,8 @@ clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. +This revised file migrates the Terraform configurations and state to the latest version and does not modify the resources deployed in MongoDB Atlas. + You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). ## Usage From e643483f820cd8df61c7e90b15588b84f566bf65 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:16:16 +0200 Subject: [PATCH 14/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index ee9ef06..40da77b 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -1,6 +1,6 @@ # Convert mongodbatlas_advanced_cluster to Provider 2.0.0 schema - advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. +The advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. This revised file migrates the Terraform configurations and state to the latest version and does not modify the resources deployed in MongoDB Atlas. From ed10890a3bf5327ea0580d7ef5b3920d19b4c2e5 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:16:42 +0200 Subject: [PATCH 15/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 40da77b..242fe06 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -2,7 +2,7 @@ The advancedClusterToV2 (adv2v2) command helps you migrate previous `mongodbatlas_advanced_cluster` configurations to the new Provider 2.0.0 schema. -This revised file migrates the Terraform configurations and state to the latest version and does not modify the resources deployed in MongoDB Atlas. +This revised file migrates the Terraform configurations and state to the latest version and doesn't modify the resources deployed in MongoDB Atlas. MongoDB Atlas Provider 2.0.0 introduces a new, cleaner structure for `mongodbatlas_advanced_cluster` resources. The main changes include the use of nested attributes instead of blocks and deletion of deprecated attributes like `disk_size_gb` at root level or `num_shards`. From a9eaa909dc24dc993648781cc2890e8e544c1534 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:17:37 +0200 Subject: [PATCH 16/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 242fe06..dc1ac4c 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -33,7 +33,7 @@ You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/t ## Dynamic Blocks `dynamic` blocks are used to generate multiple nested blocks based on a set of values. -Given the different ways of using dynamic blocks, we recommend reviewing the output and making sure it fits your needs. +We recommend reviewing the output and making sure it fits your needs. ### Dynamic blocks in tags and labels From 0c6898997674e939f205c89ef87c4f415c06153c Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:19:11 +0200 Subject: [PATCH 17/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 7118b69..f721dc4 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -2,7 +2,7 @@ clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. -This revised file migrates the Terraform configurations and state to the latest version and does not modify the resources deployed in MongoDB Atlas. +This revised file migrates the Terraform configurations and state to the latest version and doesn't modify the resources deployed in MongoDB Atlas. You can find more information in the [Migration Guide: Cluster to Advanced Cluster](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/cluster-to-advanced-cluster-migration-guide). From b58b254ec0686c0e744e67bc2d291252b0919098 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:19:32 +0200 Subject: [PATCH 18/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index f721dc4..a2927cb 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -104,7 +104,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Combination of blocks with dynamic and inline expressions -Dynamic block and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. +Dynamic blocks and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. Remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl From 57f88322ec85534315ac5e3143bc46df95dbedc4 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:19:49 +0200 Subject: [PATCH 19/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index a2927cb..fb8dfbd 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -33,7 +33,7 @@ You can find [here](https://github.com/mongodb-labs/atlas-cli-plugin-terraform/t ## Dynamic Blocks `dynamic` blocks are used to generate multiple nested blocks based on a set of values. -Given the different ways of using dynamic blocks, we recommend reviewing the output and making sure it fits your needs. +We recommend reviewing the output and making sure it fits your needs. ### Dynamic blocks in tags and labels From 64c0774ab9ad11e563545b61f0fb92849abc0b04 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:20:24 +0200 Subject: [PATCH 20/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index dc1ac4c..a9d9b50 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -55,7 +55,7 @@ dynamic "tags" { ### Dynamic blocks in region_configs -You can use `dynamic` blocks for `region_configs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. +You can use `dynamic` blocks for `region_configs`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `list` of objects. This is an example of how to use dynamic blocks in `region_configs`: ```hcl From a6be82a00d6bf56b3998d58bd8c4c243d60476f5 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:20:40 +0200 Subject: [PATCH 21/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index fb8dfbd..93a056b 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -37,7 +37,7 @@ We recommend reviewing the output and making sure it fits your needs. ### Dynamic blocks in tags and labels -You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that `for_each` has an expression which is evaluated to a `map` of strings. +You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `map` of strings. You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: ```hcl tags { From 7fd778529cab5c17d702aef3ff8fdf76198c6faf Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:20:57 +0200 Subject: [PATCH 22/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 93a056b..89f4914 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -76,7 +76,7 @@ replication_specs { ### Dynamic blocks in replication_specs -You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. +You can use `dynamic` blocks for `replication_specs`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `list` of objects. This is an example of how to use dynamic blocks in `replication_specs`: ```hcl From a6df286a57a4c9a0fc382d2c046d413442edb973 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:22:14 +0200 Subject: [PATCH 23/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index a9d9b50..5710f3e 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -110,7 +110,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Combination of blocks with dynamic and inline expressions -Dynamic block and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. The recommended way to handle this is to remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. +Dynamic blocks and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. Remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. Let's see an example with `region_configs`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl From f5f57f1c9b750a465065097b0ada3cce4581c6b7 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:22:34 +0200 Subject: [PATCH 24/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index 5710f3e..aa81c53 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -112,7 +112,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p Dynamic blocks and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. Remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `region_configs`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. +Let's see an example with `region_configs`; it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl variable "replication_specs" { type = object({ From 6c0a7cbc73a4d546d1daad5dc5bfc85bb03f51b7 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:22:57 +0200 Subject: [PATCH 25/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index aa81c53..a361655 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -216,4 +216,4 @@ resource "mongodbatlas_advanced_cluster" "this" { } } ``` -This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it is supported by the plugin. +This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it's supported by the plugin. From 2c6afefeae15976ba4f15c976ac6946d86ff47ea Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:23:16 +0200 Subject: [PATCH 26/30] Update docs/command_clu2adv.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_clu2adv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 89f4914..1663ce0 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -1,6 +1,6 @@ # Convert mongodbatlas_cluster to mongodbatlas_advanced_cluster -clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. +The clusterToAdvancedCluster (clu2adv) command helps you migrate from `mongodbatlas_cluster` to `mongodbatlas_advanced_cluster` Provider 2.0.0 schema. This revised file migrates the Terraform configurations and state to the latest version and doesn't modify the resources deployed in MongoDB Atlas. From 3f5d2b2d24a84561dabe1010ad41e0deb7079512 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:38:25 +0200 Subject: [PATCH 27/30] apply feedback --- docs/command_adv2v2.md | 8 ++++---- docs/command_clu2adv.md | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index a361655..eb51b45 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -37,8 +37,8 @@ We recommend reviewing the output and making sure it fits your needs. ### Dynamic blocks in tags and labels -You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that `for_each` has an expression which is evaluated to a `map` of strings. -You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: +You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `map` of strings. +You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, for example: ```hcl tags { key = "environment" @@ -80,7 +80,7 @@ replication_specs { ### Dynamic blocks in replication_specs -You can use `dynamic` blocks for `replication_specs`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. +You can use `dynamic` blocks for `replication_specs`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `list` of objects. This is an example of how to use dynamic blocks in `replication_specs`: ```hcl @@ -112,7 +112,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p Dynamic blocks and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. Remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `region_configs`; it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. +Let's see an example with `region_configs`; it's the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl variable "replication_specs" { type = object({ diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index 1663ce0..bb70ba0 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -13,7 +13,7 @@ If you want to convert a Terraform configuration from `mongodbatlas_cluster` to atlas terraform clusterToAdvancedCluster --file in.tf --output out.tf ``` -you can also use shorter aliases, e.g.: +You can also use shorter aliases, for example: ```bash atlas tf clu2adv -f in.tf -o out.tf ``` @@ -38,7 +38,7 @@ We recommend reviewing the output and making sure it fits your needs. ### Dynamic blocks in tags and labels You can use `dynamic` blocks for `tags` and `labels`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `map` of strings. -You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, e.g.: +You can also combine the use of dynamic blocks in `tags` and `labels` with individual blocks in the same cluster definition, for exaple: ```hcl tags { key = "environment" @@ -55,7 +55,7 @@ dynamic "tags" { ### Dynamic blocks in regions_config -You can use `dynamic` blocks for `regions_config`. The plugin assumes that `for_each` has an expression which is evaluated to a `list` of objects. +You can use `dynamic` blocks for `regions_config`. The plugin assumes that the value of `for_each` is an expression which evaluates to a `list` of objects. This is an example of how to use dynamic blocks in `regions_config`: ```hcl @@ -106,7 +106,7 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p Dynamic blocks and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. Remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `regions_config`, it is the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. +Let's see an example with `regions_config`, it's the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl variable "replication_specs" { type = object({ @@ -193,4 +193,4 @@ resource "mongodbatlas_cluster" "this" { } } ``` -This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it is supported by the plugin. +This modified configuration file has the same behavior as the original one, but it doesn't have individual blocks anymore, only the `dynamic` block, so it's supported by the plugin. From eddaa8656ccabf2dd6f47a1ec1a3a7fd09019614 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Thu, 28 Aug 2025 12:22:08 +0200 Subject: [PATCH 28/30] apply more feedback --- docs/command_adv2v2.md | 6 ++++-- docs/command_clu2adv.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index eb51b45..c2ebbc1 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -110,9 +110,11 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Combination of blocks with dynamic and inline expressions -Dynamic blocks and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. Remove the individual `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. +Dynamic blocks and individual blocks for `region_configs` or `replication_specs` are not supported at the same time. To continue using this plugin, remove `region_configs` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `region_configs`; it's the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. +#### Example + +Let's see an example with `region_configs`, the same idea applies for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `region_configs` elements in a `list` variable and we want to add an additional `region_configs` with a read-only node. ```hcl variable "replication_specs" { type = object({ diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index bb70ba0..addc22f 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -104,9 +104,11 @@ If you need to use the plugin for `dynamic` block use cases not yet supported, p #### Combination of blocks with dynamic and inline expressions -Dynamic blocks and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. Remove the individual `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. +Dynamic blocks and individual blocks for `regions_config` or `replication_specs` are not supported at the same time. To continue using this plugin, remove `regions_config` or `replication_specs` blocks and use a local `list` variable with [concat](https://developer.hashicorp.com/terraform/language/functions/concat) to add the individual block information to the variable you're using in the `for_each` expression. -Let's see an example with `regions_config`, it's the same idea for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. +#### Example + +Let's see an example with `regions_config`, the same idea applies for `replication_specs`. In the original configuration file, the `mongodb_cluster` resource is used inside a module that receives the `regions_config` elements in a `list` variable and we want to add an additional `regions_config` with a read-only node. ```hcl variable "replication_specs" { type = object({ From 2459d092a87a86bddf1ed3a707b50d399f6d269f Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:50:15 +0200 Subject: [PATCH 29/30] Update docs/command_adv2v2.md Co-authored-by: lmkerbey-mdb <105309825+lmkerbey-mdb@users.noreply.github.com> --- docs/command_adv2v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index c2ebbc1..a0abf4b 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -23,7 +23,7 @@ atlas tf adv2v2 -f in.tf -o out.tf - `--file` or `-f`: Input file path containing the `mongodbatlas_advanced_cluster` configuration - `--output` or `-o`: Output file path for the converted Provider 2.0.0 configuration -- `--replaceOutput` or `-r`: Overwrite the output file if it exists, or even use the same output file as the input file +- `--replaceOutput` or `-r`: Overwrite the file at the output path if it already exists. You can pass the input file path to this flag to modify the format in-place. - `--watch` or `-w`: Keep the plugin running and watching for changes in the input file ## Examples From 45ce5d82164d8d16719a839f23830a0cc70d0714 Mon Sep 17 00:00:00 2001 From: Leo Antoli <430982+lantoli@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:54:12 +0200 Subject: [PATCH 30/30] doc replaceOutput --- docs/command_adv2v2.md | 2 +- docs/command_clu2adv.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/command_adv2v2.md b/docs/command_adv2v2.md index a0abf4b..d24f919 100644 --- a/docs/command_adv2v2.md +++ b/docs/command_adv2v2.md @@ -23,7 +23,7 @@ atlas tf adv2v2 -f in.tf -o out.tf - `--file` or `-f`: Input file path containing the `mongodbatlas_advanced_cluster` configuration - `--output` or `-o`: Output file path for the converted Provider 2.0.0 configuration -- `--replaceOutput` or `-r`: Overwrite the file at the output path if it already exists. You can pass the input file path to this flag to modify the format in-place. +- `--replaceOutput` or `-r`: Overwrite the file at the output path if it already exists. You can also modify the input file in-place. - `--watch` or `-w`: Keep the plugin running and watching for changes in the input file ## Examples diff --git a/docs/command_clu2adv.md b/docs/command_clu2adv.md index addc22f..88986b5 100644 --- a/docs/command_clu2adv.md +++ b/docs/command_clu2adv.md @@ -22,7 +22,7 @@ atlas tf clu2adv -f in.tf -o out.tf - `--file` or `-f`: Input file path containing the `mongodbatlas_cluster` configuration - `--output` or `-o`: Output file path for the converted `mongodbatlas_advanced_cluster` configuration -- `--replaceOutput` or `-r`: Overwrite the output file if it exists, or even use the same output file as the input file +- `--replaceOutput` or `-r`: Overwrite the file at the output path if it already exists. You can also modify the input file in-place. - `--watch` or `-w`: Keep the plugin running and watching for changes in the input file - `--includeMoved` or `-m`: Include the `moved blocks` in the output file