MitocGroup / recink

REciNK - Rethink Continuous Integration for JavaScript Applications
https://www.npmjs.org/package/recink
Mozilla Public License 2.0
14 stars 5 forks source link

Failed to load backend: The -state and -state-out flags cannot be set with a plan that has a remote #89

Closed eistrati closed 6 years ago

eistrati commented 6 years ago

Command failed: /var/lib/jenkins/workspace/deploy-datafactory-dii-app/bin/terraform apply -auto-approve=true -no-color -state-out=/var/lib/jenkins/workspace/deploy-datafactory-dii-app/cc-dev/wos-content/datafactory/dev/dii-app-user-data-2/.resource/terraform.tfstate /var/lib/jenkins/workspace/deploy-datafactory-dii-app/cc-dev/wos-content/datafactory/dev/dii-app-user-data-2/.resource/terraform.tfplan Failed to load backend: The -state and -state-out flags cannot be set with a plan that has a remote state. The plan itself contains the configuration for the remote backend to store state. The state will be written there for consistency.

If you wish to change this behavior, please create a plan from local state.
You may use the state flags with plans from local state to affect where
the final state is written.
stack: 
  - Error: Command failed: /var/lib/jenkins/workspace/deploy-datafactory-dii-app/bin/terraform apply -auto-approve=true -no-color -state-out=/var/lib/jenkins/workspace/deploy-datafactory-dii-app/cc-dev/wos-content/datafactory/dev/dii-app-user-data-2/.resource/terraform.tfstate /var/lib/jenkins/workspace/deploy-datafactory-dii-app/cc-dev/wos-content/datafactory/dev/dii-app-user-data-2/.resource/terraform.tfplan
  - Failed to load backend: The -state and -state-out flags cannot be set with a plan that has a remote
  - state. The plan itself contains the configuration for the remote backend to
  - store state. The state will be written there for consistency.
  - 
  - If you wish to change this behavior, please create a plan from local state.
  - You may use the state flags with plans from local state to affect where
  - the final state is written.
  - 
  - 
  -     at Promise.all.then.arr (/var/lib/jenkins/workspace/deploy-datafactory-dii-app/node_modules/execa/index.js:236:11)
  -     at process._tickDomainCallback (internal/process/next_tick.js:135:7)
eistrati commented 6 years ago

Opened feature request here: https://github.com/hashicorp/terraform/issues/16698

eistrati commented 6 years ago

@ddimitrioglo Here is what I am discovering, which might help us solve this problem:

  1. remote state
    {
    "version": 3,
    "serial": 1,
    "lineage": "[redacted]",
    "backend": {
        "type": "s3",
        "config": {
            "bucket": "[redacted]",
            "dynamodb_table": "[redacted]",
            "key": "[redacted]/terraform.tfstate",
            "profile": "[redacted]",
            "region": "us-west-2"
        },
        "hash": 13971035820901155637
    },
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {},
            "resources": {},
            "depends_on": []
        }
    ]
    }

When running terraform state pull, we get:

{
    "version": 3,
    "terraform_version": "0.11.0",
    "serial": 1,
    "lineage": "[redacted]",
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {},
            "resources": {
                "data.aws_security_group.job_sg_id_lookup_by_name": {
                    "type": "aws_security_group",
                    "depends_on": [],
                    "primary": {
                        "id": "[redacted]",
                        "attributes": {
                            "arn": "[redacted]",
                            "description": "[redacted]",
                            "filter.#": "1",
                            "filter.3161042625.name": "tag:Name",
                            "filter.3161042625.values.#": "1",
                            "filter.3161042625.values.4225430010": "job-sg",
                            "id": "[redacted]",
                            "name": "job-sg",
                            "tags.%": "1",
                            "tags.Name": "job-sg",
                            "vpc_id": "[redacted]"
                        },
                        "meta": {},
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        },
        {
            "path": [
                "root",
                "create_ec2_job_servers"
            ],
            "outputs": {},
            "resources": {
                "aws_instance.Server": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "[redacted]",
                        "attributes": {
                            "ami": "[redacted]",
                            "associate_public_ip_address": "true",
                            "availability_zone": "us-west-2a",
                            "disable_api_termination": "false",
                            "ebs_block_device.#": "0",
                            "ebs_optimized": "false",
                            "ephemeral_block_device.#": "0",
                            "iam_instance_profile": "",
                            "id": "[redacted]",
                            "instance_state": "running",
                            "instance_type": "t2.micro",
                            "ipv6_addresses.#": "0",
                            "key_name": "mg-api",
                            "monitoring": "false",
                            "network_interface.#": "0",
                            "network_interface_id": "[redacted]",
                            "primary_network_interface_id": "[redacted]",
                            "private_dns": "[redacted]",
                            "private_ip": "[redacted]",
                            "public_dns": "[redacted]",
                            "public_ip": "[redacted]",
                            "root_block_device.#": "1",
                            "root_block_device.0.delete_on_termination": "true",
                            "root_block_device.0.iops": "100",
                            "root_block_device.0.volume_size": "8",
                            "root_block_device.0.volume_type": "gp2",
                            "security_groups.#": "0",
                            "source_dest_check": "true",
                            "subnet_id": "[redacted]",
                            "tags.%": "1",
                            "tags.Name": "JobServer",
                            "tenancy": "default",
                            "volume_tags.%": "0",
                            "vpc_security_group_ids.#": "1",
                            "vpc_security_group_ids.2467603651": "[redacted]"
                        },
                        "meta": {
                            "[redacted]": {
                                "create": 600000000000,
                                "delete": 600000000000,
                                "update": 600000000000
                            },
                            "schema_version": "1"
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        }
    ]
}
  1. local state
    {
    "version": 3,
    "terraform_version": "0.11.0",
    "serial": 1,
    "lineage": "[redacted]",
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {},
            "resources": {
                "data.aws_security_group.job_sg_id_lookup_by_name": {
                    "type": "aws_security_group",
                    "depends_on": [],
                    "primary": {
                        "id": "[redacted]",
                        "attributes": {
                            "arn": "[redacted]",
                            "description": "[redacted]",
                            "filter.#": "1",
                            "filter.3161042625.name": "tag:Name",
                            "filter.3161042625.values.#": "1",
                            "filter.3161042625.values.4225430010": "job-sg",
                            "id": "[redacted]",
                            "name": "job-sg",
                            "tags.%": "1",
                            "tags.Name": "job-sg",
                            "vpc_id": "[redacted]"
                        },
                        "meta": {},
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        },
        {
            "path": [
                "root",
                "create_ec2_job_servers"
            ],
            "outputs": {},
            "resources": {
                "aws_instance.Server": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "[redacted]",
                        "attributes": {
                            "ami": "[redacted]",
                            "associate_public_ip_address": "true",
                            "availability_zone": "us-west-2a",
                            "disable_api_termination": "false",
                            "ebs_block_device.#": "0",
                            "ebs_optimized": "false",
                            "ephemeral_block_device.#": "0",
                            "iam_instance_profile": "",
                            "id": "[redacted]",
                            "instance_state": "running",
                            "instance_type": "t2.micro",
                            "ipv6_addresses.#": "0",
                            "key_name": "mg-api",
                            "monitoring": "false",
                            "network_interface.#": "0",
                            "network_interface_id": "[redacted]",
                            "primary_network_interface_id": "[redacted]",
                            "private_dns": "[redacted]",
                            "private_ip": "[redacted]",
                            "public_dns": "[redacted]",
                            "public_ip": "[redacted]",
                            "root_block_device.#": "1",
                            "root_block_device.0.delete_on_termination": "true",
                            "root_block_device.0.iops": "100",
                            "root_block_device.0.volume_size": "8",
                            "root_block_device.0.volume_type": "gp2",
                            "security_groups.#": "0",
                            "source_dest_check": "true",
                            "subnet_id": "[redacted]",
                            "tags.%": "1",
                            "tags.Name": "JobServer",
                            "tenancy": "default",
                            "volume_tags.%": "0",
                            "vpc_security_group_ids.#": "1",
                            "vpc_security_group_ids.2467603651": "[redacted]"
                        },
                        "meta": {
                            "[redacted]": {
                                "create": 600000000000,
                                "delete": 600000000000,
                                "update": 600000000000
                            },
                            "schema_version": "1"
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        }
    ]
    }

When running terraform state pull, we get:

Empty state (no state)
eistrati commented 6 years ago

Let's summarize the workflow:

  1. terraform init
  2. terraform state pull
  3. terraform plan -out=terraform.plan
    • if ${remoteState} file doesn't exist and ${localState} file exists, add -state=${localState}
  4. terraform apply -auto-approve=true
    • if ${remoteState} file doesn't exist and ${localState} file exists, add -state=${localState} and -state-out=${localState} and -backup=${backupState}
    • if ${remoteState} file doesn't exist and ${localState} file doesn't exist and ${plan} file exists, add ${plan} instead of folder
    • after terraform apply, if ${remoteState} file exists, backup previous remote state and terraform pull state from step (2)
  5. terraform destroy -force
    • if ${remoteState} file doesn't exist and ${localState} file exists, add -state=${localState} and -state-out=${localState} and -backup=${backupState}
    • after terraform destroy, if ${remoteState} file exists, backup previous remote state and terraform pull state from step (2)
ddimitrioglo commented 6 years ago

@eistrati, maybe it makes sense to separate logic with Remote State and Cached State?

For example:

terraform:
    use-remove: true # <== default false 
    use-cache: true
    apply: true
    vars: 
      ...
use-remove: true use-remove: false
terraform init terraform init
terraform state pull download cache
terraform plan terraform plan
terraform apply terraform apply
terraform destroy terraform destroy
terraform state push upload cache

Does it make sense?

eistrati commented 6 years ago

Discussed and clarified. Will go with earlier proposed workflow.

eistrati commented 6 years ago

Checked.