What is Terraform?
Terraform is a tool to build and modify infrastructure in a secure way. It enables managing the infrastructure of services such as Google Cloud Platform, AWS, Azure and many more. Starting your adventure with ’cloud’ services with a specific service provider, the infrastructure is created by web console and by ’clicking’ on necessary resources.
The moment we need to create a second environment, either if it’s a developer one, test or demo, constant ’clicking’ may be irritating.
Then why not trying to write a code, thanks to which we would be able to create all necessary environments by configuring only differences between them, such as name of the project, where the project is localized.
With the use of Terraform we’re able to do that.
Below I’m going to present an example of how to create an essential infrastructure in order to deploy a simple application Spring Boot with the connection to the Cloud SQL base.
Module is a container for all of the resources, which we need. Modules help with understanding, grouping the infrastructure and they enable multiplying resources of the same kind, e.g. we create an instance of database out of static IP. This kind of base is needed in dev environment as well as in prod environment. Thus we define one module, which includes resources needed to create such instance. We also use this module in dev environment as well as in prod environment, only configuration values such as instance name or static IP.
State of infrastructure
Terraform has to store current state of infrastructure and configuration. This state is used to compare and to find differences between the current state of infrastructure and what is written in the code.By default the state is stored in a local file called ”terraform.tfstate”, but it can be also stored in remote server, for instance in Cloud Storage in order to ensure better automatization of implementations.
The command terraform init is used to initialize folders containing configuration files. It’s the first command, which should be executed after writing the code. By default, terraform init assumes that the folder that we work with, contains module that is the basis for creating resources. There is an option of state initialization from the remote server, which is used in this example. To use the state from the remote server the backend-init flag has to be added.
terraform init -backend-config="credentials=CREDENTIALS_FILE_PATH”
The command terraform plan is used to prepare the execution plan, which presents what has to be done to achieve the state of infrastructure on the grounds of the ”terraform.tfstate” file.
The command apply is used to making changes that are needed to achieving the desirable state prepared by the plan execution of terraform plan.
Before writing the infrastructure there are manual steps that have to be undertaken, otherwise it is impossible to create resources.
The first step is to make the project that where the environment is going to be created. If it wasn’t done while initializing cloud it can be executed by the command cloud project create.
gcloud project create PROJECT_NAME
To gain access to create the infrastructure in GCP we have to have appropriate permissions. For that, we’re going to use a service account, more specifically, a generated key allowing authorization.
We make sure if you’re working at the right project
gcloud config get-value project
If not, we change it.
gcloud config set project PROJECT_NAME
Then we create a service account.
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME
Next we create a private key for the account.
gcloud iam service-accounts keys create FILE_NAME --iam-account=SERVICE_ACCOUNT_EMAIL
FILE_NAME – file name, where they key will be saved SERVICE_ACCOUNT_EMAIL – email of the service account. If you don’t know it, you can write down all service accounts using
gcloud iam service-accounts list
Depending on resources that are used, we have to give access to our service account, so it can manage data bases among others.
gcloud projects add-iam-policy-binding PROJECT_NAME --member serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com --role roles/cloudsql.admin
We can write down all the available roles
gcloud iam roles list
Roles, that will be needed depend on the resources are to be created. In this example we will need
roles/container.adminmanagement of all Kubernetes resources
roles/cloudsql.adminmanagement of Cloud SQL resources
roles/storage.objectViewrreading of resources in storage, e.g. docker images
State of infrastructure
Terraform has state of infrastructure, that is current resources and configuration of our environment.By automatization of implementations it is impossible to keep this configuration locally. It should be kept in Cloud storage, more specifically in bucket. To create this we will use gsutil tool, which is installed by default from Google Cloud SDK.
gsutil mb -p PROJECT_NAME -c regional -l LOCATION gs://BUCKET_NAME/
To read and save this state of environment our previously created service account has to have roles/storage.object.admin role
gcloud projects add-iam-policy-binding PROJECT_NAME --member serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com --role roles/storage.admin
In the next part, I will present an example in which we will create the environment that we will need to deploy a simple Spring Boot + PostgreSQL application to the Google Kubernetes Engine.