-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid overriding the specified backend configuration in the user's input #288
Comments
|
Do you mean the deletion happened when updating the configuration? In my opinion, we need to execute |
I think initContainer is ok. |
A database is successfully provisioned, its password is changed. Will a new database will be created? |
Sorry, I can't get your point. Do you mean that we should restore the terraform state before executing |
I mean the backend might lose, and a new database might get provisioned if you reassign the backend again. |
In my opinion, the state is stored in remote backend in most cases except the |
Correct. But how do you plan to back up the state as we might have various backend types? |
Sorry for the late reply. I draw a flowchart to show how the terraform-controller job works. The newly added steps are labeled and start with graph TD
A[terraform-controller job starts] --> B(initContainer0: copy the confguration from configmap to the workDir)
B --> C(initContainer1: optional, clone git repo to the workDir)
C --> D(initContainer2: `terraform init`)
D --> E{initContainer2: check if there is a valid backend configuration}
E --> |Yes| J(New: Container: `terraform sate push`, restore the terraform state)
J --> F(Container: `terraform apply` or `terraform destroy`)
E --> |No| G(New: initContainer2: create backend.tf in the workdir, and write official k8s backend configuration to it)
G --> H(New: initContainer2: exec `terraform init` again)
H --> J
F --> I(New: Container: `terraform state pull`, store it into the backup secret)
I --> K[terraform-controller job ends]
Here are more details:
The above is all the details I can think of. If there is something I didn't consider, or there are some mistakes, please let me know :). |
Here are some concerns:
|
Thanks for the reply! @zzxwill
|
So how can you tell when it's the first time of
How did you know
How does
|
I think we can determine whether it's the first time of
I find that the
Sorry, but what do you mean by "the natural state pushing"? |
What's a backup secret?
That works. But some users use their customed terraform container, in which they embedded their private Terraform provider. In this way, we will lose the feature.
After terraform apply, terraform itself will do state pushing. |
@loheagn With our deep discussion, we find it's complex to figure out whether a remote HCL contains Terraform backend or not, and there is a high probability that the proposal will lead to the instability of our simple terraform apply/destroy retry mechanism. Here is a possible solution: We ask end-users to tell us whether there is a custom Terraform backend and what it is in the Configuration spec. What's your idea? |
In this way, when should we backup and restore the terraform state? |
We don't manually backup and restore. If end-users don't specifically set a backend, we set the default Kubernetes backend, or we use the customed one. Terraform itself will automatically keep the state as it does now. |
Okay, I understand. Actually, I was confused as to why we should backup and restore manually the terraform state as the Terraform will store its state in the backend itself…… So, the second point of the LFX issue #239 doesn't seem necessary, does it? |
My bad. The second point is essential. It means to backup Terraform Backend state to the external storage system, like AWS S3, Alibaba Cloud OSS, or some local storage system. And we need to allow end-users to restore the state. These will do great help if a disaster happened like a crash of the k8s cluster. |
OK. So we also need to provide some options in the configuration yaml for the end-users to configure there state-backup-location. And, should the “backup and restore” actions happen only when the end-users choose to use the default official k8s backend, or should we backup the backend state whatever backend type they use? |
Hi, @zzxwill I updated the flowchart: graph TD
A[terraform controller starts] --> L(pre-check and generate the configuration meta)
L --> T(New: Optional: read the backup tf state and store it into a configmap)
T --> M[start job]
M --> B(initContainer0: copy the confguration from configmap to the workDir)
B --> C(initContainer1: optional, clone git repo to the workDir)
C --> D(initContainer2: terraform init)
D --> E(New: Optional: initContainer3: mount the configmap which contains the backup tf state and push the backup data to the remote backend useing `terraform state push`)
E --> F(Container: terraform apply or terraform destroy)
F --> I(New: Container: terraform state pull, store it into the backup secret)
I --> K[job ends]
K --> N{New: Is the job successful?}
N --> |Y| O{New: Is the backend type the official kubernetes backend?}
O --> |Y| P(read the tf state from the state secret)
O --> |N| Q(New: create a working dir, and add a backend.tf file which contains the backend configuration code to the dir)
Q --> R(New: execute `terraform init` and `terraform pull`, and read the tf state from the stdout)
R --> S(New: store the tf state json to the location specified by the user in the configuration yaml file)
P --> S
|
@loheagn Let's open another issue to track the Generally, |
OK. So, the concluation is that, we should allow the end-users to specifie the backend configuration when they use git configurations, and the specification may like the following: apiVersion: terraform.core.oam.dev/v1beta1
kind: Configuration
metadata:
name: alibaba-rds-mysql-hcl
spec:
remote: https://github.com/kubevela-contrib/terraform-modules.git
path: alibaba/rds
# backend specification example for git type
backend:
type: s3
config:
bucket: "mybucket"
key: "path/to/my/key"
region: "my-region"
variable:
instance_name: "poc"
account_name: "oamtest"
password: "Xyfff83jfewGGfaked"
security_ips:
- "0.0.0.0/0"
- "192.168.1.34"
writeConnectionSecretToRef:
name: rds-conn
namespace: default If the end-users use the inline HCL configuration, we will parse the HCL code manually and detect the backend declaration in the rendering stage. If we can not detect any backend declarations, we will use the default kubernetes backend type. If there is no problem with this proposal, I think I can make a PR to implement it first and then we can discuss the details about the |
The sample of backend looks good to me, which is more native. While Terraform users tends to set the backend as below.
So do you think we should also support the inline way to set a backend? |
I think it's ok. We can support both two ways. Another question, if the user provid the backend declaration both in the inline hcl code and in the configuration yaml directly, what's the priority? |
spec.backend comes first as it's users' intention. And it would be better if we throw the warning in the Configuration status. |
Get it. Thanks for your guidance! @zzxwill |
This issue discusses how to detect the backend configuration from the user's input Terraform configuration, which could be a piece of hcl code inlined in the
terraform.core.oam.dev/Configuration
yaml file or a few text files in a remote git repository, to avoid overriding the specified backend configuration in the user's input with the default k8s configuration.As the
terraform init && terraform apply
will be split intoterraform init
andterraform apply
two stages in #284 , we may be able to use the following method to solve the above mentioned problem.Do nothing about the backend configuration in the rendering stage.
If
terraform init
executes successfully, then we can perform the following steps before terraform apply :Check if there is a
terraform.tfstate
file in the.terraform
directory.If there is, it means that the user's input configuration contains a valid backend statement. It's not necessary to add the default k8s backend configuration to the user's input and we can directly do
terraform apply.
(Actually, theterraform.tfstate
file is a json file which contains a backend block, we can parse the json to get more information about the backend configuration if necessary.)If there is not, it means that the user's input configuration doesn't contain a valid backend statement. We need to add a
backend.tf
file to the working directory and write the default k8s configuration to the file and execteffaform init
again to apply this change. As other work, such as preparing the providers, is done in the first terraform init, the second execution is "light" and it only needs to handle the newly added backend statement.Compared with the previous solution (which detects the backend configuration in the rendering stage):
Advantages
Avoid executing
terraform init
from scratch twice.It doesn't matter if the configuration is inline code or a separate git repository.
Disadvantages
The text was updated successfully, but these errors were encountered: