diff --git a/specs/2023.2/terraform-infra-driver.rst b/specs/2023.2/terraform-infra-driver.rst new file mode 100644 index 00000000..7766367c --- /dev/null +++ b/specs/2023.2/terraform-infra-driver.rst @@ -0,0 +1,427 @@ +.. + This work is licensed under a Creative Commons Attribution 3.0 Unported + License. + + http://creativecommons.org/licenses/by/3.0/legalcode + + +============================================================ +Terraform Infra-driver for VNF Instantiation and Termination +============================================================ + +This specification describes Terraform Infra-driver in Tacker. The scope of the +present document includes VNF instantiation and termination with this new +infra-driver, using AWS as an example NFVI. + +https://blueprints.launchpad.net/tacker/+spec/terraform-infra-driver + + +Problem description +=================== + +Tacker is designed as a G-VNFM that supports both VNF and CNF LCM. However, +OpenStack is the only platform where Tacker can deploy VNF among the variety of +cloud platforms. Given the recent multi-cloud trends in cloud computing, Tacker +have to overcome this potential disadvantage by implementing additional +infra-driver. + + +Proposed change +=============== + +This spec proposes to support Terraform infra-driver. Terraform [#terraform]_ +is the de-facto standard in the IaC area, it's platform-agnostic, declarative +and open source. Using Terraform as a backend tool enables Tacker to create +virtual resources on several platforms that Terraform has already supported, +such as AWS. Terraform has its own configuration language to define virtual +resources, like manifest in Kubernetes or Helm chart in Helm. Users can easily +create VNF packages for Terraform infra-driver by including the configuration. + +For this to happen, the following items have to be implemented. + +* VNF Instantiation with Terraform Infra-driver +* VNF Termination with Terraform Infra-driver +* Adding DB table/field to store Terraform state (optional) +* Sample VNF packages for Terraform infra-driver +* Updating user document + +Terraform +--------- + +HashiCorp Terraform is an infrastructure as code tool that lets you define both +cloud and on-prem resources in human-readable configuration files that you can +version, reuse, and share. Put simply, you can see Terraform as generic +OpenStack Heat that can be used among several cloud platforms. Terraform +supports a number of cloud infrastructure providers such as: + +* Amazon Web Services +* Cloudflare +* Microsoft Azure +* IBM Cloud +* Serverspace +* Google Cloud Platform +* DigitalOcean +* Oracle Cloud Infrastructure +* Yandex.Cloud +* VMware vSphere +* OpenStack +* Kubernetes +* Helm + +Terraform uses declarative configuration to describe the desired final state +and its client-side is provided only a CLI tool, similar to Helm. Therefore, +the basic architecture of Terraform infra-driver can be similar to Helm +infra-driver. + +The following are the characteristics of Terraform: + +#. Configuration file + Terraform has its own language HCL for the resource definition. The files + containing Terraform code are often called configuration files. These files + correspond to the Helm chart in Helm. +#. Variables + Terraform allows users to define variables in configuration files. + Variables can be set as a file or parameters of Terraform CLI. This is a + similar mechanism to the values in Helm. +#. State file and state lock file + Terraform creates a state file and a state lock file [#tf_state]_ when + Terraform creates actual resources. This might be the biggest difference + from Helm. This state file records the information of resources created by + Terraform. The state lock file prevents others from acquiring the lock and + potentially corrupting your state in the case where multiple users manage + the same resources with Terraform in different places. + +.. note:: In Kubernetes, the state file corresponds to the resources on + Kubernetes worker nodes which store all information of actual resources + managed by Kubernetes. As there's no entity corresponding to the worker + nodes, Terraform creates state files. + +This figure shows the overview of the operation of Terraform, and input/output +files. + +.. uml:: + + @startuml + + + actor "User" as user + component "Terraform CLI" as cli + component "Terraform" as tf + component "Configuration file" as config + component "Variables file" as vars + component "Target Service" as svc + file "State file" as state + file "State lock file" as statelock + + '# Relationships + user --> config: 1. Create Configuration file + user --> vars: 1. Create Variables file + user -> cli + cli -> tf: 2. Init Terraform\n with configuration file\n and variables file + tf --> statelock: 3. Create state lock file + cli -> tf: 4. Apply Configuration file + tf -> svc: 5. Call APIs + tf --> state: 6. Create state file + + @enduml + + +Terraform Infra-driver +---------------------- + +This figure shows an overview of Instantiate VNF with the Terraform +infra-driver. Terminate VNF is omitted as it is almost the same as the +Instantiate VNF. + +Instantiate VNF consist of the following steps: + +#. Request create VNF + Users request create VNF with a VNF package that contains Terraform config + and variable files in addition to VNFD. +#. Request instantiate VNF + Users request instantiate VNF with an instantiate parameters that can + overrides variables defined in Terraform variables file. +#. Execute Terraform command + Terraform infra-driver executes terraform command to apply configuration + files to Terraform. +#. Call target service API + Terraform calls target service APIs according to the configuration file. +#. Create VM(s) + Target service (e.g., OpenStack Nova, AWS EC2, etc) creates VM(s). + +.. uml:: + + @startuml + + frame "python-tackerclient" { + component "tacker-client" as client { + package "VNF Package" as vnfpkg { + file "VNFD" as vnfd + file "Terraform\nconfiguration" as tffile + file "Terraform\nvariables\nfile" as tfvar + } + file "Instantiate\nparameters" as inst_param + } + } + + vnfd -[hidden]> tffile + tffile-[hidden]> tfvar + + frame "tacker" { + component "tacker-server" { + component "server" as serv + } + component "tacker-conductor" { + component "conductor" as cond + component "Terraform\ninfra-driver" as infra + } + } + + node "Terraform" + + node "Target Service" as ts + cloud "Hardware Resources" as hw { + node "VM" as ins1 + } + + '# Relationships + vnfpkg --> serv: 1. Request\n create VNF + inst_param --> serv: 2. Request\n instantiate VNF + serv --> cond + cond --> infra + infra --> Terraform: 3. Execute Terraform command + Terraform -right-> ts: 4. Call target\n service API + ts --> ins1: 5. Create VM(s) + + @enduml + + + +State file management +````````````````````` + +Given that terraform config file is located in VNF packages, state files are +created and managed for each VNF instance. Terraform provides several options +(i.e., backend) to store the state file [#tf_state_backend]_. Based on the +available backend, the available options for Tacker are the following: + +#. Store state files as a local file +#. Store state files in InstantiatedVnfInfo +#. Store state files in a new DB table/field +#. Store state files in Kubernetes Secret +#. Store state files in PostgresDB + +The first option is the easiest way. As Tacker extracts a VNF package into a +local directory, we can place a state file in that local directory. However, +this makes creating more than one VNF instance from one VNF package almost +impossible. Thus, practically, we need to create another directory for each VNF +instance, copy all contents of a VNF package and keep the state file there. + +If the first option is not possible, for example, there is no way to create +temporal directories, we can manage the state file on the InstantiatedVnfInfo +field. Since the data type of this field is structure [#sol003]_ and the state +file is written in JSON, we can directly store the state file in that field. +This field is also suitable in the sense that the lifecycle of the state file +matches that of the VNF Instance. + +The rest of the options are not recommended as it incurs changes on the data +model of Tacker or requires another component to manage the state file. + +This figure shows the basic idea of the first option. + +.. uml:: + + @startuml + + left to right direction + + component "Terraform infra-driver" as tfid + folder "VNF Package A" as pkga + folder "VNF Package B" as pkgb + folder "Directory for VNF Instance A" as da { + file "Configuration" as ca + file "Variables" as va + file "State file A" as statea + file "State lock file A" as statelocka + } + folder "Directory for VNF Instance B" as db { + file "Configuration" as cb + file "Variables" as vb + file "State lock file B" as statelockb + file "State file B" as stateb + } + folder "Directory for VNF Instance C" as dc { + file "Configuration" as cc + file "Variables" as vc + file "State lock file C" as statelockc + file "State file C" as statec + } + dc -[hidden]> db + db -[hidden]> da + component "Terraform" as tf + + '# Relationships + tfid -> tf: Execute + tfid <-up- pkga: Download + tfid <-up- pkgb: Download + tfid ---> da: Copy VNF Package A + tfid ---> db: Copy VNF Package A + tfid ---> dc: Copy VNF Package B + tf --> statea: Create + tf --> statelocka: Create + tf --> stateb: Create + tf --> statelockb: Create + tf --> statec: Create + tf --> statelockc: Create + + + + @enduml + +State lock file management +`````````````````````````` + +Ideally, we can disable generating state lock files [#tf_lock]_ as Tacker is +only the entity that manages the resources associated with the instantiated +VNF. If we need to use the lock file, we have the similar options as the state +file as follows: + +#. Store state files as a local file +#. Store state files in InstantiatedVnfInfo +#. Store state files in a new DB table/field + +Alternatives +------------ + +Implementing infra-driver for individual platform can be an alternative. + +Data model impact +----------------- + +None. One possible reason for data model changes is to make new table/field to +store state and state lock files. As described in the State file management +section, we have several alternative ways. + +REST API impact +--------------- + +None. + +Security impact +--------------- + +Terraform uses sensitive data in some scenes. For example, Terraform requires +credentials to make API requests. In general, we can avoid exposure of +sensitive data by using environment variables. However, at the same time, we +need to carefully make configuration files. + +Potential risks are listed as follows, but there can be more: + +* Hardcoded credentials for the target services +* Hardcoded credentials for the backend of the state file [#tf_state_sec]_ + +See the best practice for details [#tf_sec]_ + +Notifications impact +-------------------- + +None. However, if state files are stored in InstantiatedVnfInfo, they can be +omitted from LcmOpOccNotification. + +Other end user impact +--------------------- + +None. + +Performance Impact +------------------ + +None. Terraform itself and the state file (might be located on DB) might use +storage, but it is negligibly small. As the infra-drivers are abstracted by +Tacker's VNF LCM driver, Terraform infra-driver does not affect to the overall +performance. + + +Other deployer impact +--------------------- + +After merging this feature, the following points must be considered: + +* Users need to install Terraform when using Terraform infra-driver +* Tacker community should add installation of Terraform in Zuul to tests + Terraform infra-driver + +No effects on existing deployments as this is a new feature independent of the +existing ones. + +Developer impact +---------------- + +* Developers may need to update Terraform infra-driver according to the update + of Terraform. +* Developers may need to fix bugs of Terraform infra-driver caused by the + Terraform. +* Developers may need to be careful to change other components than Terraform + infra-driver, such as VNF package format, controllers, conductor, etc, so + that it works in Terraform infra-driver. + +Implementation +============== + +Assignee(s) +----------- + +Primary assignee: + * Hiromu Asahina (hiromu) + +Other contributors: + * TBD + +Work Items +---------- + +* VNF Instantiation with Terraform Infra-driver +* VNF Termination with Terraform Infra-driver +* Adding DB table/field to store Terraform state (optional) +* Sample VNF packages for Terraform infra-driver +* Updating user document + + +Dependencies +============ + +* Terraform v1.4.0 or later + +Testing +======= + +Terraform supports several providers including OpenStack [#tf_os]_, Kubernetes +[#tf_k8s]_, Docker [#tf_local]_ and local files [#tf_docker]_. The easiest way +is to use OpenStack in the functional tests. As terraform infra-driver is +transparent for VNF packages, its normality must not be affected by the +difference of used providers. In this sense, we can test its normality with +other available providers, such as Kubernetes, docker or local provider. + +Alternatively, we can use LocalStack [#localstack]_ that acts as a stub of AWS +services. + +Documentation Impact +==================== + +Need to explain the use cases of Terraform infra-driver. + +References +========== + +.. [#terraform] https://www.terraform.io/ +.. [#tf_state] https://developer.hashicorp.com/terraform/language/state +.. [#tf_state_backend] https://developer.hashicorp.com/terraform/language/settings/backends/configuration#available-backends +.. [#sol003] https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.05.01_60/gs_NFV-SOL003v030501p.pdf +.. [#tf_lock] https://developer.hashicorp.com/terraform/language/state/locking +.. [#tf_os] https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest +.. [#tf_k8s] https://registry.terraform.io/providers/hashicorp/kubernetes/latest +.. [#tf_docker] https://registry.terraform.io/providers/kreuzwerker/docker/latest +.. [#tf_local] https://registry.terraform.io/providers/hashicorp/local/latest +.. [#tf_state_sec] https://developer.hashicorp.com/terraform/language/settings/backends/configuration#credentials-and-sensitive-data +.. [#tf_sec] https://cycode.com/7-terraform-security-best-practices/ +.. [#localstack] https://localstack.cloud/