title: Migrate terraform modules to updated provider format
body: <p>I inherited a codebase with all providers stored inside modules and am having a lot of trouble moving the providers out so that I can remove the resources created from modules.</p>
  <p>The current design violates the rules outlined here: <a href="https://www.terraform.io/docs/configuration/providers.html" rel="nofollow noreferrer">https://www.terraform.io/docs/configuration/providers.html</a> and makes removing modules impossible.</p>
  <p>My understanding of the migration steps is:</p>
  <ol>
  <li>Create a provider for use at the top-level</li>
  <li>Update module resources to use providers stored outside of the module</li>
  <li>Remove module (with top-level provider persisting)</li>
  </ol>
  <h2>Example module</h2>
  <p>An example <code>/route53-alias-record/main.ts</code> is:</p>
  <pre class="lang-hcl prettyprint-override"><code>variable &quot;evaluate_target_health&quot; {
    default = true
  }
  
  data &quot;terraform_remote_state&quot; &quot;env&quot; {
    backend = &quot;s3&quot;
  
    config = {
      bucket = &quot;&lt;bucket&gt;&quot;
      key    = &quot;infra-${var.environment}-${var.target}.tfstate&quot;
      region = &quot;&lt;region&gt;&quot;
    }
  }
  
  provider &quot;aws&quot; {
    region              = data.terraform_remote_state.env.outputs.region
    allowed_account_ids = data.terraform_remote_state.env.outputs.allowed_accounts
  
    assume_role {
      role_arn = data.terraform_remote_state.env.outputs.aws_account_role
    }
  }
  
  resource &quot;aws_route53_record&quot; &quot;alias&quot; {
    zone_id = data.terraform_remote_state.env.outputs.public_zone_id
    name    = var.fqdn
    type    = &quot;A&quot;
  
    alias {
      name                   = var.alias_name
      zone_id                = var.zone_id
      evaluate_target_health = var.evaluate_target_health
    }
  }
  </code></pre>
  <h2>Starting usage</h2>
  <pre class="lang-hcl prettyprint-override"><code>module &quot;api-dns-alias&quot; {
    source      = &quot;../environment/infra/modules/route53-alias-record&quot;
    environment = &quot;${var.environment}&quot;
    zone_id     = &quot;${module.service.lb_zone_id}&quot;
    alias_name  = &quot;${module.service.lb_dns_name}&quot;
    fqdn        = &quot;${var.environment}.example.com&quot;
  }
  </code></pre>
  <h2>Provider overriding</h2>
  <pre class="lang-hcl prettyprint-override"><code>## Same as inside module
  provider &quot;aws&quot; {
    region              = data.terraform_remote_state.env.outputs.region
    allowed_account_ids = data.terraform_remote_state.env.outputs.allowed_accounts
  
    assume_role {
      role_arn = data.terraform_remote_state.env.outputs.aws_account_role
    }
  }
  
  module &quot;api-dns-alias&quot; {
    source      = &quot;../environment/infra/modules/route53-alias-record&quot;
    environment = &quot;${var.environment}&quot;
    zone_id     = &quot;${module.service.lb_zone_id}&quot;
    alias_name  = &quot;${module.service.lb_dns_name}&quot;
    fqdn        = &quot;${var.environment}.example.com&quot;
  
    providers = {
      aws = aws ## &lt;-- pass in explicitly
    }
  }
  </code></pre>
  <p>I was able to safely deploy with the providers set, but I do not believe that they are being used inside the module, which means the handshake still fails when I remove the module and the resources cannot be deleted.</p>
  <p>I am looking for the steps needed to migrate to an outside provider so that I can safely remove resources.</p>
  <p>I am currently working with terraform <code>0.12.24</code></p>