# States

`x-install` utilizes a number of Terraform modules to manage the underlying AWS
resources required by X-IO. This implementation model ensures that the outcome of
every run of a subcommand is driven by the current state of these Terraform
modules.

If Terraform detected no drifts between the modules' desired and actual states,
no changes will be made to the AWS resources. Re-invoking the `x-install`
subcommands result in read-only operations.

On the other hand, if the modules configuration have changed or the underlying
AWS resources have drifted from the modules specification, `x-install` lets
Terraform perform the necessary reconciliation operations. This might cause some
resources to be deleted and recreated.

These Terraform modules are auto-installed by `x-install` using the `precheck`
command. The download locations can be determined by using the `x-install version`
command.

For air-gapped environment, these modules can be downloaded from the `x-install`
release page. `x-install` supports local installation of these modules using the
`--module-src-dir` flag. Use the `-h` flag to see the full description of the
`--module-src-dir` flag.

## Modules Overview

### xio

The `xio` module defines all the resources required to run X-IO. It is installed
by the `apply` subcommand.

### xio-iam

The `xio-iam` module defines the IAM resources required by X-IO. It is depended
by the `xio` module. The `precheck` command will auto-install this module if the
required IAM resources are missing in the target environment.

### infra-eks

The `infra-eks` module is used by the `create-standalone` subcommand to provision a
new VPC, EKS cluster and all the underlying AWS resources required by VPC and EKS.
No X-IO components are installed by this module.

### xkarpenter

The `xkarpenter` module uses the Terraform Helm module to install the xKarpenter in
the target EKS cluster. It depends on the `xio` module to provide the X-IO
Management Server private IP address.

## States Persistence

When an `x-install` subcommand is run, it attempts to initialize the X-IO
provider by checking for the existence of states files for the specified standalone
stack or EKS cluster. If no states files are found, `x-install` will create a new
state subfolder under `~/.xio`. This new state subfolder will be named after the
standalone stack or EKS cluster.

For example, when the `create-standalone` command completed, `x-install` will 
create a new state subfolder named `xio-standalone` under `~/.xio`, which looks 
like this:

```sh
$ tree ~/.xio/xio-standalone                                                                                             
/home/isim/.xio/xio-standalone
├── infra-k8s.state
│   ├── main.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
├── xio-iam.state
│   ├── main.tf
│   └── terraform.tfstate
├── xio.state
│   ├── main.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── xkarpenter.state
    ├── main.tf
    └── terraform.tfstate
```

Notice that all the X-IO Terraform modules have their own state subfolder. If
debugging is required, user can access issue Terraform commands (like `validate`,
`plan` etc.) directly in these folders to determine how Terraform will behave
in certain scenarios.

When working with existing EKS cluster, `x-install` will create new state subfolders
only for the `xio-iam`, `xio` and `xkarpenter` modules:

```sh
$ tree ~/.xio/xio-standalone
/home/isim/.xio/xio-standalone
├── xio-iam.state
│   ├── main.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── xio.state
    ├── main.tf
    ├── terraform.tfstate
    └── terraform.tfstate.backup
└── xkarpenter.state
    ├── main.tf
    ├── terraform.tfstate
    └── terraform.tfstate.backup
```

## Overriding Module Configuration

Every module's configuration including its input variables in defined in their
respective `main.tf` files. Once the `main.tf` file is created, `x-install` will
not modify its content on subsequent runs of the same command to avoid accidental
changes to the underlying AWS resources.

To change the content of a `main.tf`, use the `--override-existing-params` flag. This
will be useful in scenarios where users want to change certain resource-specific
configuration like e.g., the EC2 SSH key pair name. Such overrides normally cause
the deletion of the existing resources.
