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

idSeparator not changed to new format on upgrade #30

Open
dbirks opened this issue Feb 17, 2020 · 11 comments
Open

idSeparator not changed to new format on upgrade #30

dbirks opened this issue Feb 17, 2020 · 11 comments

Comments

@dbirks
Copy link

dbirks commented Feb 17, 2020

Describe the bug

When upgrading from 0.6.0 to 0.7.0, I get this error message for each k8s_manifest:

Error: unexpected ID format ("/api/v1/namespaces/dev"), expected "namespace::groupVersion::kind::name".

Steps to reproduce the issue:

Updated the provider binary locally from 0.6.0 to 0.7.0, and updated the version number in the provider block. Then I ran terraform apply and got the error.
This also happened when trying to upgrade directly to 0.7.2.

Expected behavior

I think I expected the provider to change the idSeparator in my state file automatically.

Thanks for the help!

@kim0
Copy link

kim0 commented Feb 24, 2020

I just hit this one too and am stuck! Reading the code (Thx @bonifaido ) that introduced this 7d91b1a
And don't see any code to autoconvert the IDs! I agree that having this is probably a must, bec anyone who used the old versions cannot upgrade.

If there's any workarounds to convert the IDs let us know! Thanks

@kim0
Copy link

kim0 commented Feb 27, 2020

cc @sagikazarmark @bonifaido
I'm stuck on this one .. Any advice how to proceed, please let me know. Thanks!

@kim0
Copy link

kim0 commented Mar 31, 2020

@pepov Congrats on the new release! Can we interest anyone to take a look here please :)

@pepov
Copy link

pepov commented Mar 31, 2020

@kim0 I would recommend removing the current state and importing resources back using the new version. Are there any issues with that?

@pepov
Copy link

pepov commented Mar 31, 2020

I mean removing the resources from the state and imprting them back one-by-one.

@kim0
Copy link

kim0 commented Apr 18, 2020

I went through this painful exercise yesterday. It wasn't very clear what the new ID should be, I'm leaving some examples below in case others find this bug later and need them. For my first k8s cluster, I deleted terraform state rm and imported the resources again while guessing the ID formats. For other clusters, I found it easier to edit the state file directly. A bit more dangerous, but leaves things as they are and doesn't apply the same config to a live cluster which I feel better about


terraform import module.sbr1.module.collector.k8s_manifest.configmap "default::v1::configmap::collectorenv"
terraform import module.sbr1.module.collector.k8s_manifest.deployment "default::apps/v1::deployment::collector"
terraform import module.sbr1.module.collector.k8s_manifest.hpa "default::autoscaling/v1::HorizontalPodAutoscaler::collector"
terraform import module.sbr1.module.collector.k8s_manifest.ingress "default::networking.k8s.io/v1beta1::Ingress::collector"
terraform import module.sbr1.module.collector.k8s_manifest.secrets "default::v1::secret::collector"
terraform import module.sbr1.module.collector.k8s_manifest.slave_headless "default::v1::service::slave-headless"
terraform import module.sbr1.module.collector.k8s_manifest.svc "default::v1::service::collector"
terraform import module.sbr1.module.helm.k8s_manifest.redis_region_master_pdb "default::policy/v1beta1::PodDisruptionBudget::redis-region-master-pdb"
terraform import module.sbr1.module.helm.k8s_manifest.redis_slaveofeu_pdb "default::policy/v1beta1::PodDisruptionBudget::redis-slaveofeu-pdb"

@dmarkey
Copy link

dmarkey commented Apr 24, 2020

This backwards incompatible change is pretty bad.. What was the rational and what was the expectation for people upgrading?

@sagikazarmark
Copy link
Member

@dmarkey we've forked and rewritten the provider to a better structure. The rational was to make it work with terraform better (the original provider was not perfect to say the least) You're welcome.

You are free to NOT upgrade if you don't want to (or can't). We don't expect you to do anything...with this free and open source project.

Alternatively (as a side note), you can contact us for professional support: https://banzaicloud.com/contact/. We can help you upgrade your terraform state.

@dmarkey
Copy link

dmarkey commented Apr 24, 2020

Don't get me wrong. I am extremely grateful for you maintaining this fork.

I assume you have scripts internally written to do the upgrade instead at hacking at statefiles? Perhaps releasing that would solve this issue.

@sagikazarmark
Copy link
Member

We did what @pepov mentioned above: reimported resources (which is something that we implemented in the provider). If it's not possible for some reason, manual editing should still be a no brainer.

@LavaToaster
Copy link

Just incase anyone else gets this and comes here, and has too many resources to care rewriting or importing. I wrote a script in node that you can use to rewrite the ids.

Warning: I'm not sure if it matters, but be sure to specify what api kinds are global, without a namespace. The ones included are the only ones in the configuration I'm dealing with, yours might have more especially if you run cert-manager.

Run:

npm install yaml

Create a file called rewrite.js.

const state = require('./state.json');
const yaml = require('yaml');
const fs = require('fs');

console.log(`k8s_manifest state fixer\n\n`);

const kindNoNamespace = [
    'Namespace',
    'ClusterRole',
    'ClusterRoleBinding',
]

for (let module of state.modules) {
    for (let resource of Object.values(module.resources)) {
        if (resource.type === 'k8s_manifest') {
            if (!resource.primary.id.startsWith('/')) {
                continue;
            }

            let yamlString = resource.primary.attributes.content;
            let { kind, apiVersion, metadata: { name, namespace = 'default' } } = yaml.parse(yamlString);

            if (kindNoNamespace.includes(kind)) {
                namespace = '';
            }

            let newId = `${namespace}::${apiVersion}::${kind}::${name}`;
            console.log(newId);

            resource.primary.id = newId;
            resource.primary.attributes.id = newId;
        }
    }
}

fs.writeFile('./state.json', JSON.stringify(state, null, 4), (err) => {
    if (err) throw err;
    console.log('State has been updated!');
});
terraform state pull > state.json
node rewrite.js
# check the output of state.json is correct
$ terraform state push state.json

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

No branches or pull requests

6 participants