When refreshing remote state, indicate when no state file was found with
an ErrRemoteStateNotFound error. This prevents us from inadvertantly
getting a nil state into a terraform.State where we assume there's
always a root module.
This commit makes the current Terraform state version 3 (previously 2),
and a migration process as part of reading v2 state. For the most part
this is unnecessary: helper/schema will deal with upgrading state for
providers written with that framework. However, for providers which
implemented the resource model directly, this gives a best-efforts
attempt at lossless upgrade.
The heuristics used to change the count of a map from the .# key to the
.% key are as follows:
- if the flat map contains any non-numeric keys, we treat it as a
map
- if the map is empty it must be computed or optional, so we remove
it from state
There is a known edge condition: maps with all-numeric keys are
indistinguishable from sets without access to the schema. They will need
manual conversion or may result in spurious diffs.
This commit forward ports the changes made for 0.6.17, in order to store
the type and sensitive flag against outputs.
It also refactors the logic of the import for V0 to V1 state, and
fixes up the call sites of the new format for outputs in V2 state.
Finally we fix up tests which did not previously set a state version
where one is required.
- Fix sensitive outputs for lists and maps
- Fix test prelude which was missed during conflict resolution
- Fix `terraform output` to match old behaviour and not have outputs
header and colouring
- Bump timeout on TestAtlasClient_UnresolvableConflict
This commit adds the groundwork for supporting module outputs of types
other than string. In order to do so, the state version is increased
from 1 to 2 (though the "public-facing" state version is actually as the
first state file was binary).
Tests are added to ensure that V2 (1) state is upgraded to V3 (2) state,
though no separate read path is required since the V2 JSON will
unmarshal correctly into the V3 structure.
Outputs in a ModuleState are now of type map[string]interface{}, and a
test covers round-tripping string, []string and map[string]string, which
should cover all of the types in question.
Type switches have been added where necessary to deal with the
interface{} value, but they currently default to panicking when the input
is not a string.
Adds the `TF_SKIP_REMOTE_TESTS` env var to be used in cases where the
`http.Get()` smoke test passes but the network is not able to service
the needs of the tests.
Fixes#4421
The retryablehttp package implements basic retries w/ exponential
backoff, which helps the remote state push recover in cases of
connectivity blips or transient errors.
Atlas returns an HTTP 409 - Conflict if the pushed state reports the same
Serial number but the checksum of the raw content differs. This can
sometimes happen when Terraform changes state representation internally
between versions in a way that's semantically neutral but affects the JSON
output and therefore the checksum.
Here we detect and handle this situation by ticking the serial and retrying
iff for the previous state and the proposed state:
* the serials match
* the parsed states are Equal (semantically equivalent)
In other words, in this situation Terraform can override Atlas's detected
conflict by asserting that the state it is pushing is indeed correct.
The state is always JSON, in spite of the fact that this interface
presents it as an opaque byte array. It's more helpful to those interacting
with the state object outside of Terraform for it to have a more specific
content-type.
This change allows the user to specify `-backend-config="encrypt=1"`
to tell S3 to encrypt the data that's in the bucket when using S3
for remote config storage.
The encryption uses "Amazon S3-managed encryption keys" so it should
not require any further user intervention.
A line was added to the unit test just for coverage.
The acceptance test was modified to:
a) Use encryption
b) Push some test data up to the bucket created to ensure
that Amazon accepts the header.
/cc @LeftyBC - Hope this helps! Some basic point:
* Idiomatic Go is to use thisCasingStyle and not this_casing_style
* Less repetitive to just create an http.Client once and re-use, also
more flexible for later.
* The empty `if ok {}` was kind of awkward, replace with proper check