Tfedit - A refactoring tool for Terraform

Related tags

DevOps Tools tfedit
Overview

tfedit

License: MIT GitHub release GoDoc

Features

Easy refactoring Terraform configurations in a scalable way.

  • CLI-friendly: Read HCL from stdin, apply filters and write results to stdout, easily pipe and combine other commands.
  • Keep comments: You can update lots of existing Terraform configurations without losing comments.
  • Available operations:
    • filter awsv4upgrade: Upgrade configurations to AWS provider v4. Only aws_s3_bucket refactor is supported.

For upgrading AWS provider v4, some rules have not been implemented yet. The current implementation status is as follows:

S3 Bucket Refactor

  • acceleration_status Argument
  • acl Argument
  • cors_rule Argument
  • grant Argument
  • lifecycle_rule Argument
  • logging Argument
  • object_lock_configuration rule Argument
  • policy Argument
  • replication_configuration Argument
  • request_payer Argument
  • server_side_encryption_configuration Argument
  • versioning Argument
  • website, website_domain, and website_endpoint Arguments

Although the initial goal of this project is providing a way for bulk refactoring of the aws_s3_bucket resource required by breaking changes in AWS provider v4, but the project scope is not limited to specific use-cases. It's by no means intended to be an upgrade tool for all your providers. Instead of covering all you need, it provides reusable building blocks for Terraform refactoring and shows examples for how to compose them in real world use-cases.

As you know, Terraform refactoring often requires not only configuration changes, but also Terraform state migrations. However, it's error-prone and not suitable for CI/CD. For declarative Terraform state migration, use tfmigrate.

If you are not ready for the upgrade, you can pin version constraints in your Terraform configurations with tfupdate.

Install

Source

If you have Go 1.17+ development environment:

$ go install github.com/minamijoyo/[email protected]
$ tfedit version

Usage

$ tfedit --help
A refactoring tool for Terraform

Usage:
  tfedit [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  filter      Apply a built-in filter
  help        Help about any command
  version     Print version

Flags:
  -f, --file string   A path of input file (default "-")
  -h, --help          help for tfedit
  -u, --update        Update files in-place

Use "tfedit [command] --help" for more information about a command.
$ tfedit filter --help
Apply a built-in filter

Arguments:
  FILTER_TYPE    A type of filter.
                 Valid values are:
                 - awsv4upgrade
                   Upgrade configurations to AWS provider v4.
                   Only aws_s3_bucket refactor is supported.

Usage:
  tfedit filter <FILTER_TYPE> [flags]

Flags:
  -h, --help   help for filter

Global Flags:
  -f, --file string   A path of input file (default "-")
  -u, --update        Update files in-place

By default, the input is read from stdin, and the output is written to stdout. You can also read a file with -f flag, and update the file in-place with -u flag.

Example

Given the following file:

$ cat ./test-fixtures/awsv4upgrade/aws_s3_bucket.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.0.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "example" {
  bucket = "minamijoyo-tf-aws-v4-test1"
  acl    = "private"

  logging {
    target_bucket = "minamijoyo-tf-aws-v4-test1-log"
    target_prefix = "log/"
  }
}
$ tfedit filter awsv4upgrade -f ./test-fixtures/awsv4upgrade/aws_s3_bucket.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.0.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "example" {
  bucket = "minamijoyo-tf-aws-v4-test1"

}

resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.example.id
  acl    = "private"
}

resource "aws_s3_bucket_logging" "example" {
  bucket = aws_s3_bucket.example.id

  target_bucket = "minamijoyo-tf-aws-v4-test1-log"
  target_prefix = "log/"
}

License

MIT

Comments
  • aws_s3_bucket_versioning with mfa_delete needs status = Enabled

    aws_s3_bucket_versioning with mfa_delete needs status = Enabled

    resource "aws_s3_bucket" "global_cloudtrail_logs" {
      bucket        = "cloudtrail-logs"
    
      versioning {
        mfa_delete = true
      }
    }
    

    Is translated to:

    resource "aws_s3_bucket" "global_cloudtrail_logs" {
      bucket = "cloudtrail-logs"
    }
    
    resource "aws_s3_bucket_versioning" "global_cloudtrail_logs" {
      bucket = aws_s3_bucket.global_cloudtrail_logs.id
    
      versioning_configuration {
        mfa_delete = "Enabled"
      }
    }
    

    This isn't quite correct, it should also have status

    resource "aws_s3_bucket_versioning" "whim_global_cloudtrail_logs" {
      bucket = aws_s3_bucket.whim_global_cloudtrail_logs.id
    
      versioning_configuration {
        status     = "Enabled"
        mfa_delete = "Enabled"
      }
    }
    

    Relates to #40

    opened by danielcompton 3
  • mfa_delete is set incorrectly on aws_s3_bucket_versioning resources

    mfa_delete is set incorrectly on aws_s3_bucket_versioning resources

    When upgrading an aws_s3_bucket resource that is using MFA delete the aws_s3_bucket_versioning resource that gets created sets the mfa_delete value to true when it should be "Enabled"

    opened by mogggggg 2
  • Custom provider not copied to new resources

    Custom provider not copied to new resources

    If you set a provider on an S3 resource, it's not copied to the child S3 resources

    resource "aws_s3_bucket" "bucket" {
      provider = aws.ohio
      bucket   = "mybucket"
      acl      = "private"
    }
    

    After migration:

    resource "aws_s3_bucket" "bucket" {
      provider = aws.ohio
      bucket   = "mybucket"
    }
    
    resource "aws_s3_bucket_acl" "bucket" {
      bucket = aws_s3_bucket.bucket.id
      acl    = "private"
    }
    

    This will cause an error when you try and import:

    │ Error: error getting S3 bucket ACL (bucket,private): AuthorizationHeaderMalformed: The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'us-east-2'
    
    opened by danielcompton 1
  • aws_s3_bucket_lifecycle_configuration: empty filter and tags causes a drift on import

    aws_s3_bucket_lifecycle_configuration: empty filter and tags causes a drift on import

    Summary

    When aws_s3_bucket.lifecycle_rule.filter and tags were empty in AWS v3, importing aws_s3_bucket_lifecycle_configuration in AWS v4 with tfmigrate plan will be failed due to detecting a drift.

    When both filter and tags were empty in v3, just removing the empty filter in v4 converges the drift. This looks like a similar problem to #29, but actually a different one.

    Version

    $ tfedit version
    0.0.3
    
    $ tfmigrate -v
    0.3.3
    
    $ terraform -v
    Terraform v1.2.1
    on linux_amd64
    + provider registry.terraform.io/hashicorp/aws v4.15.1
    

    Configuration

    AWS v3.74.3

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    
      lifecycle_rule {
        id      = "log"
        enabled = true
        prefix  = ""
        tags    = {}
    
        noncurrent_version_transition {
          days          = 30
          storage_class = "GLACIER"
        }
    
        noncurrent_version_expiration {
          days = 90
        }
      }
    }
    

    AWS v4.15.1

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      rule {
        id = "log"
    
        noncurrent_version_transition {
          storage_class   = "GLACIER"
          noncurrent_days = 30
        }
    
        noncurrent_version_expiration {
          noncurrent_days = 90
        }
        status = "Enabled"
    
        filter {
    
          and {
            prefix = ""
            tags   = {}
          }
        }
      }
    }
    

    Expected behavior

    $ terraform plan -out=tmp.tfplan
    $ terraform show -json tmp.tfplan | tfedit migration fromplan -o=tfmigrate_fromplan.hcl
    $ cat tfmigrate_fromplan.hcl
    migration "state" "fromplan" {
      actions = [
        "import aws_s3_bucket_lifecycle_configuration.example tfedit-test",
      ]
    }
    
    $ tfmigrate plan tfmigrate_fromplan.hcl
    (snip.)
    YYYY/MM/DD hh:mm:ss [INFO] [migrator] state migrator plan success!
    

    Actual behavior

    $ tfmigrate plan tfmigrate_fromplan.hcl
    2022/05/27 09:47:02 [INFO] [runner] load migration file: tfmigrate_fromplan.hcl
    2022/05/27 09:47:02 [INFO] [migrator] start state migrator plan
    2022/05/27 09:47:02 [INFO] [[email protected]] terraform version: 1.2.1
    2022/05/27 09:47:02 [INFO] [[email protected]] initialize work dir
    2022/05/27 09:47:05 [INFO] [[email protected]] get the current remote state
    2022/05/27 09:47:06 [INFO] [[email protected]] override backend to local
    2022/05/27 09:47:06 [INFO] [[email protected]] create an override file
    2022/05/27 09:47:06 [INFO] [[email protected]] creating local workspace folder in: terraform.tfstate.d/default
    2022/05/27 09:47:06 [INFO] [[email protected]] switch backend to local
    2022/05/27 09:47:10 [INFO] [[email protected]] compute a new state
    2022/05/27 09:47:24 [INFO] [[email protected]] check diffs
    2022/05/27 09:47:39 [ERROR] [[email protected]] unexpected diffs
    2022/05/27 09:47:39 [INFO] [[email protected]] remove the override file
    2022/05/27 09:47:39 [INFO] [[email protected]] remove the workspace state folder
    2022/05/27 09:47:39 [INFO] [[email protected]] switch back to remote
    terraform plan command returns unexpected diffs: failed to run command (exited 2): terraform plan -state=/tmp/tmp783177411 -out=/tmp/tfplan2179793936 -input=false -no-color -detailed-exitcode
    stdout:
    aws_s3_bucket.example: Refreshing state... [id=tfedit-test]
    aws_s3_bucket_lifecycle_configuration.example: Refreshing state... [id=tfedit-test]
    
    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:
    
      # aws_s3_bucket_lifecycle_configuration.example will be updated in-place
      ~ resource "aws_s3_bucket_lifecycle_configuration" "example" {
            id     = "tfedit-test"
            # (1 unchanged attribute hidden)
    
          ~ rule {
                id     = "log"
                # (1 unchanged attribute hidden)
    
              ~ filter {
                  + and {}
                }
    
    
                # (2 unchanged blocks hidden)
            }
        }
    
    Plan: 0 to add, 1 to change, 0 to destroy.
    
    ─────────────────────────────────────────────────────────────────────────────
    
    Saved the plan to: /tmp/tfplan2179793936
    
    To perform exactly these actions, run the following command to apply:
        terraform apply "/tmp/tfplan2179793936"
    
    stderr:
    
    opened by minamijoyo 1
  • aws_s3_bucket_website_configuration: An argument named

    aws_s3_bucket_website_configuration: An argument named "routing_rules" is not expected here.

    Summary

    In AWS v3, aws_s3_bucket.website.routing_rules is a string which is a JSON array contains routing rules. In AWS v4, aws_s3_bucket_website_configuration.routing_rule is a block. We need to parse json and build corresponding blocks representation.

    https://registry.terraform.io/providers/hashicorp/aws/3.74.3/docs/resources/s3_bucket#website https://registry.terraform.io/providers/hashicorp/aws/4.14.0/docs/resources/s3_bucket_website_configuration

    Version

    $ tfedit version
    0.0.3
    
    $ terraform -v
    Terraform v1.1.9
    on darwin_amd64
    + provider registry.terraform.io/hashicorp/aws v4.14.0
    

    Expected behavior

    tmp/iss30/main.tf

    before

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    
      website {
        index_document = "index.html"
        error_document = "error.html"
    
        routing_rules = <<EOF
    [{
        "Condition": {
            "KeyPrefixEquals": "docs/"
        },
        "Redirect": {
            "ReplaceKeyPrefixWith": "documents/"
        }
    }]
    EOF
      }
    }
    
    $ cat tmp/iss30/main.tf | tfedit filter awsv4upgrade
    

    after

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_website_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      index_document {
        suffix = "index.html"
      }
    
      error_document {
        key = "error.html"
      }
    
      routing_rule {
        condition {
          key_prefix_equals = "docs/"
        }
        redirect {
          replace_key_prefix_with = "documents/"
        }
      }
    }
    

    Actual behavior

    $ cat tmp/iss30/main.tf | tfedit filter awsv4upgrade
    
    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_website_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      index_document {
        suffix = "index.html"
      }
    
      error_document {
        key = "error.html"
      }
    
    
      routing_rules = <<EOF
    [{
        "Condition": {
            "KeyPrefixEquals": "docs/"
        },
        "Redirect": {
            "ReplaceKeyPrefixWith": "documents/"
        }
    }]
    EOF
    }
    
    opened by minamijoyo 1
  • Fix invalid filter and tags for aws_s3_bucket_lifecycle_configuration

    Fix invalid filter and tags for aws_s3_bucket_lifecycle_configuration

    Fixes #29, #35

    Non-empty tags should be wrapped by an and block.

    When both prefix and tags are empty but defined, it will result in a migration plan diff, so remove them and put an empty filter.

    opened by minamijoyo 0
  • Suppress creating a migration file when no action

    Suppress creating a migration file when no action

    Fixes #33

    It is not only redundant but also causes an error as an invalid migration file when loaded by tfmigrate. Intentionally does not return errors, so we can ignore irrelevant directories when processing multiple directories.

    opened by minamijoyo 0
  • aws_s3_bucket_lifecycle_configuration: days_after_initiation = 0 causes a drift on import

    aws_s3_bucket_lifecycle_configuration: days_after_initiation = 0 causes a drift on import

    Summary

    When aws_s3_bucket.lifecycle_rule.abort_incomplete_multipart_upload_days was explicitly set to 0 in AWS v3, importing aws_s3_bucket_lifecycle_configuration.abort_incomplete_multipart_upload.days_after_initiation = 0 in AWS v4 with tfmigrate plan will be failed due to detecting a drift.

    According to the implementation, the zero value is explicitly skipped setting the parameter: https://github.com/hashicorp/terraform-provider-aws/blob/v3.74.3/internal/service/s3/bucket.go#L2266-L2271 https://github.com/hashicorp/terraform-provider-aws/blob/v4.15.1/internal/service/s3control/bucket_lifecycle_configuration.go#L291-L293

    After applying tfmigrate with force mode, then terraform apply with AWS v4 converges the drift. I'm not sure whether this is a bug of the AWS provider or not.

    Version

    $ tfedit version
    0.0.3
    
    $ tfmigrate -v
    0.3.3
    
    $ terraform -v
    Terraform v1.2.1
    on linux_amd64
    + provider registry.terraform.io/hashicorp/aws v4.15.1
    

    Configuration

    AWS v3.74.3

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    
      lifecycle_rule {
        id                                     = "test"
        enabled                                = true
        abort_incomplete_multipart_upload_days = 0
      }
    }
    

    AWS v4.15.1

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      rule {
        id     = "test"
        status = "Enabled"
    
        filter {
          prefix = ""
        }
    
        abort_incomplete_multipart_upload {
          days_after_initiation = 0
        }
      }
    }
    

    Expected behavior

    $ terraform plan -out=tmp.tfplan
    $ terraform show -json tmp.tfplan | tfedit migration fromplan -o=tfmigrate_fromplan.hcl
    $ cat tfmigrate_fromplan.hcl
    migration "state" "fromplan" {
      actions = [
        "import aws_s3_bucket_lifecycle_configuration.example tfedit-test",
      ]
    }
    
    $ tfmigrate plan tfmigrate_fromplan.hcl
    (snip.)
    YYYY/MM/DD hh:mm:ss [INFO] [migrator] state migrator plan success!
    

    Actual behavior

    $ tfmigrate plan tfmigrate_fromplan.hcl
    2022/05/27 09:03:59 [INFO] [runner] load migration file: tfmigrate_fromplan.hcl
    2022/05/27 09:03:59 [INFO] [migrator] start state migrator plan
    2022/05/27 09:03:59 [INFO] [[email protected]] terraform version: 1.2.1
    2022/05/27 09:03:59 [INFO] [[email protected]] initialize work dir
    2022/05/27 09:04:02 [INFO] [[email protected]] get the current remote state
    2022/05/27 09:04:03 [INFO] [[email protected]] override backend to local
    2022/05/27 09:04:03 [INFO] [[email protected]] create an override file
    2022/05/27 09:04:03 [INFO] [[email protected]] creating local workspace folder in: terraform.tfstate.d/default
    2022/05/27 09:04:03 [INFO] [[email protected]] switch backend to local
    2022/05/27 09:04:07 [INFO] [[email protected]] compute a new state
    2022/05/27 09:04:21 [INFO] [[email protected]] check diffs
    2022/05/27 09:04:36 [ERROR] [[email protected]] unexpected diffs
    2022/05/27 09:04:36 [INFO] [[email protected]] remove the override file
    2022/05/27 09:04:36 [INFO] [[email protected]] remove the workspace state folder
    2022/05/27 09:04:36 [INFO] [[email protected]] switch back to remote
    terraform plan command returns unexpected diffs: failed to run command (exited 2): terraform plan -state=/tmp/tmp3105549665 -out=/tmp/tfplan2994504524 -input=false -no-color -detailed-exitcode
    stdout:
    aws_s3_bucket.example: Refreshing state... [id=tfedit-test]
    aws_s3_bucket_lifecycle_configuration.example: Refreshing state... [id=tfedit-test]
    
    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:
    
      # aws_s3_bucket_lifecycle_configuration.example will be updated in-place
      ~ resource "aws_s3_bucket_lifecycle_configuration" "example" {
            id     = "tfedit-test"
            # (1 unchanged attribute hidden)
    
          ~ rule {
                id     = "test"
                # (1 unchanged attribute hidden)
    
              + abort_incomplete_multipart_upload {
                  + days_after_initiation = 0
                }
    
              - expiration {
                  - days                         = 0 -> null
                  - expired_object_delete_marker = false -> null
                }
    
                # (1 unchanged block hidden)
            }
        }
    
    Plan: 0 to add, 1 to change, 0 to destroy.
    
    ─────────────────────────────────────────────────────────────────────────────
    
    Saved the plan to: /tmp/tfplan2994504524
    
    To perform exactly these actions, run the following command to apply:
        terraform apply "/tmp/tfplan2994504524"
    
    stderr:
    
    opened by minamijoyo 0
  • The `tfedit migration fromplan` command should suppress creating a migration file when no action

    The `tfedit migration fromplan` command should suppress creating a migration file when no action

    Summary

    The tfedit migration fromplan command should suppress creating a migration file when no action.

    The current implementation generates a migration file with no action even if terraform plan has no changes. It is not only redundant, but also causes an error as an invalid migration file when loaded by tfmigrate.

    Version

    $ tfedit version
    0.0.3
    
    $ terraform -v
    Terraform v1.1.9
    on darwin_amd64
    + provider registry.terraform.io/hashicorp/aws v4.14.0
    
    $ tfmigrate -v
    0.3.3
    

    Expected behavior

    If terraform plan has no changes, should not create a migration file.

    $ terraform plan -out=tmp.tfplan
    $ terraform show -json tmp.tfplan | tfedit migration fromplan -o=tfmigrate_fromplan.hcl
    $ cat tfmigrate_fromplan.hcl
    cat: tfmigrate_fromplan.hcl: No such file or directory
    

    Actual behavior

    $ terraform plan -out=tmp.tfplan
    $ terraform show -json tmp.tfplan | tfedit migration fromplan -o=tfmigrate_fromplan.hcl
    $ cat tfmigrate_fromplan.hcl
    migration "state" "fromplan" {
      actions = [
      ]
    }
    
    $ tfmigrate plan tfmigrate_fromplan
    (snip.)
    
    faild to NewMigrator with no actions
    
    opened by minamijoyo 0
  • aws_s3_bucket_lifecycle_configuration: An argument named

    aws_s3_bucket_lifecycle_configuration: An argument named "tags" is not expected here.

    Summary

    An tags argument of aws_s3_bucket_lifecycle_configuration should be wrapped in and block. When both tags and filter arguments are defined, it works as expected. However, when only tags is defined and filter is not defined, the result doesn't wraps tags with and block. Note that tags parameter is only valid in and block in schema.

    https://registry.terraform.io/providers/hashicorp/aws/3.74.3/docs/resources/s3_bucket#lifecycle_rule https://registry.terraform.io/providers/hashicorp/aws/4.14.0/docs/resources/s3_bucket_lifecycle_configuration

    Version

    $ tfedit version
    0.0.3
    
    $ terraform -v
    Terraform v1.1.9
    on darwin_amd64
    + provider registry.terraform.io/hashicorp/aws v4.14.0
    

    Expected behavior

    tmp/iss29/main.tf

    before

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    
      lifecycle_rule {
        id      = "log"
        enabled = true
    
        tags = {
          rule      = "log"
          autoclean = "true"
        }
    
        transition {
          days          = 30
          storage_class = "STANDARD_IA"
        }
    
        transition {
          days          = 60
          storage_class = "GLACIER"
        }
    
        expiration {
          days = 90
        }
      }
    
      lifecycle_rule {
        id      = "tmp"
        prefix  = "tmp/"
        enabled = true
    
        expiration {
          days = 90
        }
      }
    }
    
    $ cat tmp/iss29/main.tf | tfedit filter awsv4upgrade
    

    after

    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      rule {
        id = "log"
    
    
        transition {
          days          = 30
          storage_class = "STANDARD_IA"
        }
    
        transition {
          days          = 60
          storage_class = "GLACIER"
        }
    
        expiration {
          days = 90
        }
        status = "Enabled"
    
        filter {
    
          and {
            prefix = ""
            tags = {
              rule      = "log"
              autoclean = "true"
            }
          }
        }
      }
    
      rule {
        id = "tmp"
    
        expiration {
          days = 90
        }
        status = "Enabled"
    
        filter {
          prefix = "tmp/"
        }
      }
    }
    

    Actual behavior

    $ cat tmp/iss29/main.tf | tfedit filter awsv4upgrade
    
    resource "aws_s3_bucket" "example" {
      bucket = "tfedit-test"
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "example" {
      bucket = aws_s3_bucket.example.id
    
      rule {
        id = "log"
    
    
        transition {
          days          = 30
          storage_class = "STANDARD_IA"
        }
    
        transition {
          days          = 60
          storage_class = "GLACIER"
        }
    
        expiration {
          days = 90
        }
        status = "Enabled"
    
        filter {
          prefix = ""
          tags = {
            rule      = "log"
            autoclean = "true"
          }
        }
      }
    
      rule {
        id = "tmp"
    
        expiration {
          days = 90
        }
        status = "Enabled"
    
        filter {
          prefix = "tmp/"
        }
      }
    }
    
    opened by minamijoyo 0
  • aws_s3_bucket_lifecycle_configuration: The argument

    aws_s3_bucket_lifecycle_configuration: The argument "id" is required, but no definition was found

    I noticed that in AWS v3, aws_s3_bucket.lifecycle_rule.id argument is optional and computed. https://registry.terraform.io/providers/hashicorp/aws/3.74.3/docs/resources/s3_bucket#lifecycle_rule

    However in AWS v4, aws_s3_bucket_lifecycle_configuration.rule.id argument is now required. https://registry.terraform.io/providers/hashicorp/aws/4.14.0/docs/resources/s3_bucket_lifecycle_configuration#id

    This means that if the id is omitted in the configuration, there is no way to know the id without reading tfstate or calling AWS API with aws s3api get-bucket-lifecycle-configuration --bucket <bucketname>. https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-lifecycle-configuration.html

    opened by minamijoyo 0
  • Preserve comments on noncurrent_version_expiration

    Preserve comments on noncurrent_version_expiration

    resource "aws_s3_bucket" "mybucket" {
      bucket = "mybucket"
    
      lifecycle_rule {
        id      = "cleanup"
        enabled = true
    
        expiration {
          days = 14 # mark as expired 14 days after creation
        }
    
        noncurrent_version_expiration {
          days = 14 # delete expired 14 days after they expired
        }
      }
    }
    

    loses the comments on noncurrent_version_expiration after filtering

    resource "aws_s3_bucket" "mybucket" {
      bucket = "mybucket"
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "mybucket" {
      bucket = aws_s3_bucket.mybucket.id
    
      rule {
        id = "cleanup"
    
        expiration {
          days = 14 # mark as expired 14 days after creation
        }
    
        noncurrent_version_expiration {
          noncurrent_days = 14
        }
        status = "Enabled"
    
        filter {
          prefix = ""
        }
      }
    }
    
    opened by danielcompton 2
  • Create new resources directly below existing aws_s3_bucket resources

    Create new resources directly below existing aws_s3_bucket resources

    Firstly, thank you so much for this tool. It has saved me a lot of time and energy.

    The only manual work I needed to do with tfedit was to move the generated resources from the bottom of the file to directly below their parent s3 bucket.

    It would be great if it was possible to create the new resources in the middle of the file next to the bucket, rather than appending to the bottom of the file.

    Thanks again!

    opened by danielcompton 1
Releases(v0.1.3)
  • v0.1.2(Jul 6, 2022)

    Changelog

    • bd2ea3a Bump version to v0.1.2
    • b72d153 Fix invalid filter and tags for aws_s3_bucket_lifecycle_configuration
    • d6d80ea Use a native cache feature in actions/setup-go
    • 1cbb1d9 Suppress adding invalid days_after_initiation for aws_s3_bucket_lifecycle_configuration
    • e2de3b5 Suppress creating a migration file when no action
    • f8c09eb Map mfa_delete true/false => Enabled/Disabled for aws_s3_bucket_versioning
    Source code(tar.gz)
    Source code(zip)
    tfedit_0.1.2_checksums.txt(394 bytes)
    tfedit_0.1.2_darwin_amd64.tar.gz(3.19 MB)
    tfedit_0.1.2_darwin_arm64.tar.gz(3.04 MB)
    tfedit_0.1.2_linux_amd64.tar.gz(3.08 MB)
    tfedit_0.1.2_linux_arm64.tar.gz(2.80 MB)
  • v0.1.1(Jun 16, 2022)

  • v0.1.0(Jun 7, 2022)

  • v0.0.2(May 2, 2022)

    Changelog

    • 580b836 Bump version to v0.0.2
    • e84cfea Fix typos
    • 1e29963 Rename migration awsv4upgrade command to fromplan
    • f854faa Rename Generate to GenerateFromPlan
    • 6258cc7 Add tests for parse plan file
    • a7ee94e Return an error instead of panic
    • c9d03a1 Add tests for Conflict
    • 358fe9a Return only unresolved conflicts
    • afd5892 Add a test for unknown resource type
    • e45784c Skip generating a conflict when no-op
    • d2091b2 Add tests for StateImportResolver
    • bbac8f8 Split StateImportResolver to a file
    • c4f65c2 Rename analyzer to plan_analyzer
    • e32146a Add tests for StateMigration and StateAction
    • 013e6e9 Add tests for generating a migration file from plan
    • 2d24ce6 Add tests for dictionary
    • 8f0fa6f Fix the error message for importIDFuncAWSS3BucketACL
    • d3efc02 Split ImportIDFunc to a file and add tests
    • 18a5780 Return an error if failed to parse plan file
    • 776af50 Add support grant for import
    • 252b08d Use a raw JSON string as a test data for easy testing
    • 60c3127 Add a test for importIDFuncAWSS3BucketACL
    • 8fea92a Inject a dictionary to StateImportResolver for easy testing
    • fc5a256 Fix lint issues
    • fd73a7b Fix the sort order of test-fixtures
    • 80f0ac6 Generate migration files on acceptance tests
    • 9d52318 Allow to pass a dir attribute in a migration file
    • cf1bd13 Allow to pass a name label of migration block
    • 2e04eae Abstract problem solving so that it can be extended other than import
    • 0f0a961 Analyze a given plan and resolve conflicts and generate a migration
    • 13def48 Extract Plan as a type
    • 1ff7739 Rename File to StateMigration
    • 5192a46 Abstract Action to interface
    • 47b4aeb Rename Migration to File
    • d9e3410 Rename registerSchema to registerS3Schema
    • 01bbbf1 Update tfmigrate to v0.3.3
    • 6889205 Extract Migration as a type
    • fbb5288 Add comments for schema package
    • fa96e92 Fix a bug for binding flags
    • 4d41048 go mod tidy
    • 3df62e9 Register ImportIDFuncs for aws_s3_bucket_*
    • 9575027 Allow to inject definitions of resource type outside from package
    • f8dbf09 Allow to read a plan file from stdin
    • 2f117ed Implement a PoC for generating import commands
    Source code(tar.gz)
    Source code(zip)
    tfedit_0.0.2_checksums.txt(394 bytes)
    tfedit_0.0.2_darwin_amd64.tar.gz(2.99 MB)
    tfedit_0.0.2_darwin_arm64.tar.gz(2.93 MB)
    tfedit_0.0.2_linux_amd64.tar.gz(2.88 MB)
    tfedit_0.0.2_linux_arm64.tar.gz(2.64 MB)
  • v0.0.1(Apr 15, 2022)

    Changelog

    • d1aef8f Add CHANGELOG
    • 975c623 Setup goreleaser
    • 4e64856 Make awsv4upgrade filter as a sub command
    • 9b09e3c Fix a comment about the permission issue of git
    • 4c984c0 Fix a permission issue for CVE-2022-24765
    • 59671de Setup acceptance tests on GitHub Actions
    • 1bd0df7 Add full version for acceptance test at once
    • d28ccd1 Use valid configuration as unit tests
    • c62201c Add acceptance tests and fixtures
    • c6af445 Update examples using AWS v4.9
    • deac504 Update GitHub Actions to latest
    • fbc1187 Use a top-level object_lock_enabled for object_lock_configuration
    • f7d7bf0 Update Go to v1.17.8
    • 997e8ec Update the Getting Started guide
    • acad849 Setup localstack for testing import
    • 1e983c0 Fix regression of aws3v4ugprade filter
    • a4e4ab3 Fix typo
    • fa36165 Update golangci-lint to v1.45.2
    • 884aad5 Remove a new line token from results in SplitTokensAsList()
    • 44e85c8 Fix suppress an empty token in empty list
    • cd38f8b Add tests for SplitTokensAsList()
    • 6526c3f Add tests for File
    • 0975f76 Add tests for NestedBlock
    • 46e4495 Add tests for Attribute
    • 6e8d634 Add a test for block.VerticalFormat()
    • 4f11b96 Add tests for nested blocks
    • 8acb244 Add tests for block attribute
    • e7b7106 Add block.Type()
    • f94bafe Rename Resource.Type() to Resource.SchemaType()
    • c86e5e2 Move Type(), Name(), SetAttributeByReference() to tfwrite.Resource
    • 3b23592 Generalize Resource and NestedBlock to a new Block interface
    • 25c36c1 Add support for replication_configuration of aws_s3_bucket
    • 1633481 Add support for object_lock_configuration of aws_s3_bucket
    • 1cc825d Add support for request_payer of aws_s3_bucket
    • 8056c03 Add support for acceleration_status of aws_s3_bucket
    • 6f9c6c8 Fix how to get canonical user id
    • a6c5e78 Add support for grant of aws_s3_bucket
    • 36aeef9 Add support for website argument of aws_s3_bucket
    • 8524969 Add another limitation for versioning.enabled = false
    • 2564fb8 Convert a timestamp format for date in transition and expiration
    • bc52170 Use go-cmp for testing
    • 3d0c26d Map tags of filter for lifecycle_rule
    • 8a8fe36 Add a limitation for filter of lifecycle_rule
    • 02ef0c9 Add tests for filter in lifecycle_rule
    • 479328b Add support for cors_rule argument of aws_s3_bucket
    • 08e7977 Add support for policy argument of aws_s3_bucket
    • 4628b92 Add support for versioning
    • 1dc6e78 Add support for server_side_encryption_configuration
    • ac37781 Extract setBucketArgument to a helper method
    • ac4b459 Move the vertical formatter to tfeditor package
    • 2eb9b5a Test multiple resources on AWSS3BucketFilter
    • 6d79f10 Loop resources on AWSS3BucketFilter, not on each filter
    • 1d59c6c Add ResourceFilter to remove duplicated resources loop from each filter
    • cb9deb9 Implement a vertical format
    • 1473420 Move Attribute and NestedBlock to new files
    • 3b5c69e Add support for lifecycle_rule
    • 1911449 Allow to find multiple nested blocks
    • cde53f8 Setup CI with GitHub Actions
    • 2fd35d4 Make a resource as first class struct
    • e4a6fa7 Rename variables for readability
    • 805389f Move generic methods to tfwrite package
    • 0087d7c Add README.md
    • a1d045b Rename aws_v4_upgrade command to filter
    • 35b945a Add version command
    • 2b88aca Add test fixtures
    • 1131876 Add LICENSE
    • 09ce2be Add comments for unimplemented filters
    • d8f5009 Setup make test and lint
    • bf76e9e Add tests
    • 844768b Set an original value for acl attribute
    • a8231f1 Update short name
    • eeeb419 Remove redundant constructors for filters
    • fc11a0d Extract setBucketArgument as a method
    • aae121a Extract getResourceName as a method
    • c85fd41 Extract appendNewResourceBlock as a method
    • d11f421 Extract findResourceByType as a method
    • b05403a Split filters by argument
    • 2d8144a Use hcledit to structure rewriting logic
    • 8cde077 Implement aws_s3_bucket_logging
    • 263a126 Implement a PoC
    • f2c766a Initial commit
    Source code(tar.gz)
    Source code(zip)
    tfedit_0.0.1_checksums.txt(394 bytes)
    tfedit_0.0.1_darwin_amd64.tar.gz(2.95 MB)
    tfedit_0.0.1_darwin_arm64.tar.gz(2.88 MB)
    tfedit_0.0.1_linux_amd64.tar.gz(2.85 MB)
    tfedit_0.0.1_linux_arm64.tar.gz(2.60 MB)
Owner
Masayuki Morita
Masayuki Morita
Terraform-equinix-migration-tool - Tool to migrate code from Equinix Metal terraform provider to Equinix terraform provider

Equinix Terraform Provider Migration Tool This tool targets a terraform working

Equinix 1 Feb 15, 2022
kube-champ 42 Sep 22, 2022
Terraform-in-Terraform: Execute Modules directly from the Terraform Registry

Terraform-In-Terraform Provider This provider allows running Terraform in Terraform. This might seem insane but there are some edge cases where it com

WeakPixel 39 Aug 31, 2022
Terraform utility provider for constructing bash scripts that use data from a Terraform module

Terraform Bash Provider This is a Terraform utility provider which aims to robustly generate Bash scripts which refer to data that originated in Terra

Martin Atkins 33 Sep 6, 2022
Terraform provider to help with various AWS automation tasks (mostly all that stuff we cannot accomplish with the official AWS terraform provider)

terraform-provider-awsutils Terraform provider for performing various tasks that cannot be performed with the official AWS Terraform Provider from Has

Cloud Posse 22 Aug 26, 2022
Terraform Provider for Azure (Resource Manager)Terraform Provider for Azure (Resource Manager)

Terraform Provider for Azure (Resource Manager) Version 2.x of the AzureRM Provider requires Terraform 0.12.x and later, but 1.0 is recommended. Terra

null 0 Oct 16, 2021
Quick start repository for creating a Terraform provider using terraform-plugin-framework

Terraform Provider Scaffolding (Terraform Plugin Framework) This template repository is built on the Terraform Plugin Framework. The template reposito

HashiCorp 52 Sep 20, 2022
Terraform-provider-mailcow - Terraform provider for Mailcow

Terraform Provider Scaffolding (Terraform Plugin SDK) This template repository i

Owen Valentine 0 Dec 31, 2021
Terraform-provider-buddy - Terraform Buddy provider For golang

Terraform Provider for Buddy Documentation Requirements Terraform >= 1.0.11 Go >

Buddy 1 Jan 5, 2022
Terraform-provider-vercel - Terraform Vercel Provider With Golang

Vercel Terraform Provider Website: https://www.terraform.io Documentation: https

Vercel 65 Sep 20, 2022
Terraform-grafana-dashboard - Grafana dashboard Terraform module

terraform-grafana-dashboard terraform-grafana-dashboard for project Requirements

hadenlabs 1 May 2, 2022
Puccini-terraform - Enable TOSCA for Terraform using Puccini

(work in progress) TOSCA for Terraform Enable TOSCA for Terraform using Puccini.

Tal Liron 3 Jun 27, 2022
Terraform Provider Scaffolding (Terraform Plugin SDK)

Terraform Provider Scaffolding (Terraform Plugin SDK) This template repository is built on the Terraform Plugin SDK. The template repository built on

Brian Flad 0 Feb 8, 2022
Terraform-ncloud-docs - Terraform-ncloud-docs

terraform-ncloud-docs Overview This docs help to use terraform creation server C

Naver Cloud Platform 1 Aug 22, 2022
Terraform-provider-age - Age Terraform Provider with golang

Age Terraform Provider This provider lets you generate an Age key pair. Using th

ConsenSys Software 0 Feb 15, 2022
Terraform-house - Golang Based terraform automation example using tf.json

Terraform House Manage your own terraform workflow using go language, with the b

Bayu Rizky Ramadhan 0 Feb 17, 2022
LTF is a minimal, transparent Terraform wrapper. It makes Terraform projects easier to work with.

LTF Status: alpha LTF is a minimal, transparent Terraform wrapper. It makes Terraform projects easier to work with. In standard Terraform projects, th

Raymond Butcher 21 Sep 20, 2022
Terraform Controller manages the life cycles of a terraform resource, allowing developers to self-serve dependencies in a controlled manner.

TERRAFORM CONTROLLER Terraform Controller manages the life cycles of a terraform resource, allowing developers to self-serve dependencies in a control

appvia 50 Sep 16, 2022