Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correctly handle alias slugs on aliases reconciliation #387

Merged
merged 4 commits into from
Jul 2, 2024

Conversation

davidbloss
Copy link
Contributor

@davidbloss davidbloss commented Jun 28, 2024

Issues

Changelog

Remove stringAliasesToSetValue() - replaced by use of opslevel.UniqueIdentifiers()
Add "slugs" (non-managed aliases) from UniqueIdentifiers to aliases passed into ReconcileAliases(). This ensures we do not try to create a existing aliases while providing the flexibility for users to include or exclude slugs in their Terraform configs.

  • List your changes here
  • Make a changie entry

Tophatting

With this Terraform config, aliases = []

resource "opslevel_team" "example" {
  name    = "Test Team One"
  aliases = []

  member {
    email = "david+pat@opslevel.com"
    role  = "contributor"
  }
}

resource "opslevel_service" "example" {
  name    = "Test Service One"
  aliases = []
}

resource "opslevel_infrastructure" "example" {
  schema = "Database"
  owner  = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU0Ng"
  data = jsonencode({
    name = "my-database"
  })
  aliases = []
}

Create resources with aliases set and empty, terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # opslevel_infrastructure.example will be created
  + resource "opslevel_infrastructure" "example" {
      + aliases = []
      + data    = jsonencode(
            {
              + name = "my-database"
            }
        )
      + id      = (known after apply)
      + owner   = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU0Ng"
      + schema  = "Database"
    }

  # opslevel_service.example will be created
  + resource "opslevel_service" "example" {
      + aliases = []
      + id      = (known after apply)
      + name    = "Test Service One"
    }

  # opslevel_team.example will be created
  + resource "opslevel_team" "example" {
      + aliases = []
      + id      = (known after apply)
      + name    = "Test Team One"

      + member {
          + email = "david+pat@opslevel.com"
          + role  = "contributor"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.
opslevel_team.example: Creating...
opslevel_infrastructure.example: Creating...
opslevel_service.example: Creating...
opslevel_team.example: Creation complete after 0s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_infrastructure.example: Creation complete after 0s [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_service.example: Creation complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Add "default aliases" of Team and Service to Terraform config

resource "opslevel_team" "example" {
  name    = "Test Team One"
  aliases = ["test_team_one_2"] # <-- in aliases but not managedAliases

  member {
    email = "david+pat@opslevel.com"
    role  = "contributor"
  }
}

resource "opslevel_service" "example" {
  name    = "Test Service One"
  aliases = ["test_service_one_2"] # <-- in aliases but not managedAliases
}

resource "opslevel_infrastructure" "example" {
  schema = "Database"
  owner  = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU0Ng"
  data = jsonencode({
    name = "my-database"
  })
  aliases = [] # no defaults created here
}

Update team and service aliases, terraform apply

opslevel_infrastructure.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_service.example will be updated in-place
  ~ resource "opslevel_service" "example" {
      ~ aliases = [
          + "test_service_one_2",
        ]
        id      = "Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI"
        name    = "Test Service One"
    }

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      ~ aliases = [
          + "test_team_one_2",
        ]
        id      = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ"
        name    = "Test Team One"

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 2 to change, 0 to destroy.
opslevel_team.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]
opslevel_team.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Modifications complete after 2s [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Apply complete! Resources: 0 added, 2 changed, 0 destroyed.

Update config, replace "slugs" from aliases with new aliases

resource "opslevel_team" "example" {
  name    = "Test Team One"
  aliases = ["fancy_team"]

  member {
    email = "david+pat@opslevel.com"
    role  = "contributor"
  }
}

resource "opslevel_service" "example" {
  name    = "Test Service One"
  aliases = ["fancy_service"]
}

resource "opslevel_infrastructure" "example" {
  schema = "Database"
  owner  = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU0Ng"
  data = jsonencode({
    name = "my-database"
  })
  aliases = ["fancy_infra"]
}

Update aliases for all resources, terraform apply

opslevel_infrastructure.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_service.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]
opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_infrastructure.example will be updated in-place
  ~ resource "opslevel_infrastructure" "example" {
      ~ aliases = [
          + "fancy_infra",
        ]
        id      = "Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU"
        # (3 unchanged attributes hidden)
    }

  # opslevel_service.example will be updated in-place
  ~ resource "opslevel_service" "example" {
      ~ aliases = [
          - "test_service_one_2",
          + "fancy_service",
        ]
        id      = "Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI"
        name    = "Test Service One"
    }

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      ~ aliases = [
          - "test_team_one_2",
          + "fancy_team",
        ]
        id      = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ"
        name    = "Test Team One"

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 3 to change, 0 to destroy.
opslevel_infrastructure.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_team.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]
opslevel_team.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_infrastructure.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_service.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Apply complete! Resources: 0 added, 3 changed, 0 destroyed.

Update config, aliases omitted

resource "opslevel_team" "example" {
  name = "Test Team One"
  # aliases = ["fancy_team"]

  member {
    email = "david+pat@opslevel.com"
    role  = "contributor"
  }
}

resource "opslevel_service" "example" {
  name = "Test Service One"
  # aliases = ["fancy_service"]
}

resource "opslevel_infrastructure" "example" {
  schema = "Database"
  owner  = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU0Ng"
  data = jsonencode({
    name = "my-database"
  })
  # aliases = ["fancy_infra"]
}

Remove aliases (set to null)

opslevel_infrastructure.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_infrastructure.example will be updated in-place
  ~ resource "opslevel_infrastructure" "example" {
      - aliases = [
          - "fancy_infra",
        ] -> null
        id      = "Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU"
        # (3 unchanged attributes hidden)
    }

  # opslevel_service.example will be updated in-place
  ~ resource "opslevel_service" "example" {
      - aliases = [
          - "fancy_service",
        ] -> null
        id      = "Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI"
        name    = "Test Service One"
    }

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      - aliases = [
          - "fancy_team",
        ] -> null
        id      = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ"
        name    = "Test Team One"

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 3 to change, 0 to destroy.
opslevel_infrastructure.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_team.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_service.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]
opslevel_team.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTU4NQ]
opslevel_infrastructure.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvRW50aXR5T2JqZWN0LzI3NzQ1MzU]
opslevel_service.example: Modifications complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS8xMjU5MjI]

Apply complete! Resources: 0 added, 3 changed, 0 destroyed.

@davidbloss davidbloss merged commit 2bb83d1 into main Jul 2, 2024
4 checks passed
@davidbloss davidbloss deleted the db/fix-reconcile-aliases-again branch July 2, 2024 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants