Open Chriscbr opened 1 year ago
@ekeren @staycoolcall911 I suspect this is something we will need to consider as P1 for beta given the fact that Terraform doesn't offer support for this (so this can't even be solved using plugins).
I've bumped to P1 for now and we can discuss scope and priority for beta.
This is p1 for RFC
Did you consider making ID the key and not the value?
bring cloud;
new cloud.Bucket();
$ wing compile -t tf-aws hello.main.w
ERROR: stateful resource "/root/Bucket" doesn't have a name in the lockfile.
Please edit `hello.main.w.lock`.
$ cat hello.main.w.lock
<NEW>: /root/Bucket
$ edit hello.main.w.lock
my_s3_bucket: /root/Bucket
$ wing compile -t tf-aws hello.main.w
$ # cool!
bring cloud;
class MyStore {
new() {
new cloud.Bucket();
}
}
new MyStore();
$ wing compile -t tf-aws hello.main.w
ERROR: stateful resource "/root/MyStore/Bucket" doesn't have a name in the lockfile.
ERROR: stateful resource "/root/Bucket" with the name "my_s3_bucket" was deleted.
Please edit `hello.main.w.lock`.
$ cat hello.main.w.lock
<NOT_FOUND> my_s3_bucket: /root/Bucket
<NEW>: /root/MyStore/Bucket:
$ edit hello.main.w.lock
my_s3_bucket: /root/MyStore/Bucket
$ wing compile -t tf-aws hello.main.w
My thinking that reading the diff file from left to right will be easier(starting with the key as the constant)
some thoughts:
looks like this is inferred from the resource? Could I opt to do this manually?
Not sure I understand... what's the use case? Are you referring to custom terraform resources?
this might lead to cases where this will still destroy the resource, e.g. when constructed attribute values (e.g. a bucket name based on some other input) are forcing a re-create of the resource.
Yes, good point. This is meant to prevent resource destruction caused by identity mapping. We should also address replacement protection, which I think terraform is very lousy about... I'll spin off another issue to discuss and focus this issue.
there should be a way to ignore this via a global setting
Yes, CLI should have wing compile --no-lockfile
or something like this.
perhaps a way to isolate stateful resources in dedicated tf configs / stacks would be useful as well. Smaller changesets, faster and generally best practice anyway. See also Terraform Stacks (Terraform BSL only). But generally speaking, something like CDKTF / AWS CDK Stacks.
Yes. I am wondering if this is something we can implement as a platform provider, I'll open an issue to track.
RFC (Rev 1.)
Here's a proposal for a simple mechanism to prevent damage caused by logical name mapping changes.
If a resource is marked as
stateful
, it's Terraform resource name will be determined by looking up its path in a map stored in a<entrypoint>.w.lock
file, next to the entrypoint file, which will be committed to the repository.If an entry for this resource cannot be found in the lockfile, the compilation will fail and instruct the user to explicitly add an entry and provide a resource name.
Additionally, compilation will also fail if the file includes an entry that doesn't map to a stateful resource in the app.
This will ensure that:
We can offer some CLI commands to edit the lockfile, but that's not P1.
Here's an example.
Say I write this Wing called
hello.main.w
:Now, I compile:
Now, let's say we refactored the app and we will move the same bucket into a class:
At some point we can be smarter and offer a nice DX:
We can also offer some CLI commands to update:
Original Feature Spec
Each Wing resource has a path that represents its unique address within the resource tree. This path is used to produce a deterministic Terraform identifier for each resource (which is what Terraform uses in its state file to map to the physical resource).
When refactoring code and resources are moved around, their Terraform identifier could change. In certain cases, especially for stateful resources with important data, this could be hazardous.
Wing resources can be explicitly marked as "stateful" or "stateless". If a resource is marked as "stateful", Wing will protect it from being accidentally deleted during deployment, and will offer a way to associated the
We provide some mechanism for you to relocate the terraform identifier of a resource in order to link the old identifier to the newly placed resource.
Use Cases
In some cases, users may want their Buckets to be emptied when their app is destroyed, while in other cases users may want their Buckets to be retained if their app is destroyed. (And in further cases, users may want to configure this on a per-Bucket basis).
The same general pattern applies to any stateful resource, including Counter etc.
Implementation Notes
Sadly, and surprisingly, Terraform's
prevent_destory
attribute cannot be used to implement this feature:This means that if the resource is completely removed from the configuration, it will be destroyed in the next
apply
.There is a heated conversation in this issue.
Alternatives to consider:
sql_database_instance
).Intuitively it feels like this is something Wing should handle regardless of the provisioning system, so I believe it's worth trying to find the right mechanism.