Tuesday, 30 April 2024

VS Code Extension for YAML & Kubernetes

In VS Code's Extensions Marketplace, search for YAML and install YAML by Red Hat. 

The following steps show how to enable support for Kubernetes.

Upon installation, on extension's tab page, click on the cog and choose Extension Settings.

In settings: find Yaml: Schemas and click on Edit in settings.json

... and in that file add the following:

    "yaml.schemas": {  
        "kubernetes": "*.yaml"
    }



After this, in YAML file, type in apiVersion (the first required property of the Kubernetes YAML definition file) and auto-completion and auto-indentation for Kubernetes YAML files will kick in:

In case of errors in YAML formatting or Kubernetes YAML file not matching the Kubernetes YAML schema, this extension will show an error:





Monday, 29 April 2024

YAML Ain't Markup Language (YAML)




YAML file format is used to represent data, like other data structure formats like XML or JSON.

This table shows the same data, represented in all three formats:


Files that use YAML format can have extension .yaml or .yml

Key-Value Pair


Data in its simplest form is a key value pair and that's how it's defined in YAML: key and value separated by a colon (colon must be followed by space).

name: Server1

The key above is name
The value is Server1.


YAML file is basically a collection of one or more key-value pairs where key is a string (without quotation marks) while value is a string or some more complex data structure like a list, dictionary or list of dictionaries etc...


Sequence/Array/List


Array name is followed by colon and then each item goes in its own line with a dash in the front:


Servers:
- Server1
- Server2
...
- ServerN


The dash indicates that it's an element of an array.

In the example above we have actually a key-value pair where value is a list. As YAML document is a collection of key-value pairs, we can have a file like this:

foo.yaml:

Servers:
- Server1
- Server2

DataCentres:
- London
- Frankfurt

This style of writing sequences is called a block style. Sequences can also be written in flow style, where elements are separated by comma, within square brackets:

Servers: [Server1, Server2]
DataCentres: [London, Frankfurt]


Dictionary (Map)


A dictionary is a set of properties grouped together under an item.

Technically, the example below is a key-value pair where key is the name of the dictionary and value is the dictionary itself:

Server1:
    name: Server1
    owner: John
    created: 123456
    status: active

Notice the blank space before each property. There must be an equal number of blank spaces before the properties of a single item so they are all aligned together, meaning that they are all siblings of their parent, which is key Server1.

The number of (indentation) spaces before these properties doesn't matter. But that number should be the same as they are siblings.

A YAML file use spaces as indentation, you can use 2 or 4 spaces for indentation, but no tab. In other words, tab indentation is forbidden. [php - A YAML file cannot contain tabs as indentation - Stack Overflow]

Why does YAML forbid tabs?

Tabs have been outlawed since they are treated differently by different editors and tools. And since indentation is so critical to proper interpretation of YAML, this issue is just too tricky to even attempt. Indeed Guido van Rossum of Python has acknowledged that allowing TABs in Python source is a headache for many people and that were he to design Python again, he would forbid them. [YAML Ain't Markup Language]

Notice the number of spaces before each property that indicates these key value pairs fall within Server1

Let's suppose that we have:

Server1:
    name: Server1
    owner: John
       created: 123456
    status: active

In this case created has more spaces on the left than owner and so it is now a child of the owner property instead being its sibling, which is incorrect.

Also these properties must have more spaces than its parent which is Server1.

What if we had extra spaces for created and status?  

Server1:
    name: Server1
    owner: John
       created: 123456
       status: active

Then they will fall under owner and thus become properties of owner.  This will result in a syntax error which will tell you that mapping values are not allowed here because owner already has a value set which is John

For a value of the key-value pair we can either set a direct value or a hash map. We cannot have both. So the number of spaces before each property is key in YAML.


Complex Data Types


A list containing dictionaries 


We have here a key-value pair where value is a list of key-value pairs where value is a dictionary (we can say that we have a list of dictionaries where each dictionary has a name):

Servers:
- Server1:
    name: Server1
    owner: John
    created: 123456
    status: active
- Server2:
    name: Server2
    owner: Jack
    created: 789012
    status: shutdown


We have here a list of servers and the elements of the list are key-value pairs Server1 and Server2.
Their values are dictionaries containing server information.

We can have a list of (unnamed) dictionaries where each element of list is not a key-value pair but a dictionary itself:

 Servers:
  - name: Server1
    owner: John
    created: 123456
    status: active
  - name: Server2
    owner: Jack
    created: 789012
    status: shutdown

A list containing dictionaries containing list


Servers:
- Server1:
    name: Server1
    owner: John
    created: 123456
    status: active
    applications:
       - web server
       - authentication database
- Server2:
    name: Server2
    owner: Jack
    created: 789012
    status: shutdown
    applications:
       - caching database

When to use a list, dictionary and list of dictionaries?


Use dictionary if need to represent information or multiple properties of a single object.

Dictionary is a collection of key-value pairs grouped together:

name: Server1
owner: John
created: 123456
status: active

In case we need to split the owner further into name and surname, we could then represent this as a dictionary within another dictionary.

name: Server1
owner: 
   name: John
   surname: Smith
created: 123456
status: active

In this case the single value of owner is now replaced by a small dictionary with two properties name
and surname. So this is a dictionary within another dictionary.


Use a list/array to represent multiple items of the same type of object.  
E.g. that type could be a string.

We have here a key-value pair where value is a list of strings

Servers:
- Server1
- Server2

What if we would like to store all information about each server? We'll expand each item in the array and replace the name with the dictionary. This way we are able to represent all information about multiple servers in a single YAML file using a list of dictionaries.

We have here a key-value pair where value is a list of dictionaries:

Servers:
- name: Server1
  owner: John
  created: 123456
  status: active
- name: Server2
  owner: Jack
  created: 789012
  status: shutdown


When the order of items matter?



Dictionary is an unordered collection.
Lists/arrays are ordered collections.

Dictionary 

name: Server1
owner: John

is the same as:

owner: John
name: Server1

But list:

- Server1
- Server2

is not the same as list:

- Server2
- Server1


Comments in YAML

Any line beginning with a hash is automatically ignored and considered as a comment.

# List of servers
- Server1
- Server2


How to break long string values into multiple lines?

Use:
  • vertical bar (|) pipe character which preserves the new line
  • greater-than (>) character which folds the new line and converts it into spaces


References:


Sunday, 28 April 2024

Introduction to Kubernetes

These are custom notes that extend my notes from an Udemy course "Kubernetes for the Absolute Beginners - Hands-on". All course content rights belong to course creators. 

Introduction


Web Applications are nowadays developed with containerisation on mind as containers contain everything that is needed to run the application: code, runtime, databases, system libraries, etc.


Kubernetes (k8s) is:
  • an open-source container orchestration platform designed to automate deploying, scaling, and operating containerized applications. It’s essential for managing large-scale, distributed applications efficiently.
  • Platform for managing application containers (containerised applications, container-oriented applications, containerized workloads and services) across multiple hosts (one or more host clusters)
  • The easiest and the most recommended way to manage containers in production
  • It makes it easy to orchestrate many containers on many hosts, scale them as microservices, and easily deploy, rollouts and rollbacks
  • a set of APIs that we can use to deploy containers on a set of nodes called a cluster 
  • We can describe a set of applications and how they should interact with each other, and Kubernetes determines how to make that happen
  • Workload scheduler with focus on containerized applications.
  • Container orchestration technology -  system for automating the operations and management of application containers in complex, multi-container workloads:
    • Container creation
    • Container deployment
    • Rolling deployment *)
    • Auto-scaling
    • Load balancing
    • Container health monitoring
    • Compute resource management
    • Volume management
    • Persistent storage
    • Networking
    • High availability by cluster federation
  • Open-source
  • Originally designed by Google, based upon their running of containers in production. Now maintained by the Cloud Native Computing Foundation
  • Supports hosting enhanced and complex applications on various kinds of architectures; it is designed to run anywhere:
    • on a bare metal
    • in our data center
    • on the public cloud - supported on any cloud platform; it is platform-agnostic and integrates with a number of different cloud providers, allowing us to pick the platform that best suits our needs
    • on the hybrid cloud
  • 2 steps involved in scheduling container on a Kubernetes cluster:
    • Provisioning somewhere the Kubernetes cluster with all its components
    • Defining the Kubernetes resources, such as Deployments, Services, etc.
  • With Kubernetes:
    • we can decide when our containers should run
    • increase, or decrease the size of application containers
    • check the resource consumption of our application deployments
  • To save time and effort when scaling applications and workloads, Kubernetes can be bootstrapped using:
    • Amazon Elastic Kubernetes Service (EKS)
    • Google Kubernetes engine (GKE)

*) Rolling deployment:
  • A deployment strategy that slowly replaces previous versions of an application with new versions of an application by completely replacing the infrastructure on which the application is running;
  • It is renowned for its ability to update applications without downtime. Incrementally updating nodes or replicas ensures that the service remains available to users throughout the deployment process)
  • Rolling deployments use the concept of a window size—this is the number of servers that are updated at any given time. For example, if a Kubernetes cluster is running 10 instances of an application (10 pods), and you want to update two of them at a time, you can perform a rolling deployment with a window size of 2.


Core concepts:

  • Cluster and its components:
    • Nodes
    • Pods
    • Services
    • Deployments

Cluster


A Kubernetes cluster is a set of node machines for running containerized applications, managed by the Kubernetes control plane. 

Its components are:
  • Nodes
  • Pods
  • Services
  • Deployments
Let's explain briefly each of them.


Nodes


  • Definition: 
    • Nodes are the worker machines in a Kubernetes cluster. They can be physical machines or virtual machines.
  • Types of Nodes:
    • Master Node(s) (Control Plane): Manages the Kubernetes cluster. It runs the control plane components:
      • API Server: Exposes the Kubernetes API, acting as the entry point for all administrative tasks.
      • etcd: A distributed key-value store used to store all cluster data.
      • Scheduler: Assigns work (pods) to the nodes in the cluster based on resource availability.
      • Controller Manager: Runs various controllers that regulate the state of the cluster (e.g., Node Controller, Replication Controller).
    • Worker Node: Runs application workloads.
      • Kubelet: An agent that runs on each node and ensures containers are running in a pod.
      • Kube-proxy: Manages network rules and facilitates communication between pods and services. Maintains network rules on nodes. It handles network communication to your pods from network sessions inside or outside of the cluster.
      • Container Runtime: The software responsible for running containers (e.g., Docker, containerd). The software that runs containers, such as Docker, containerd, or CRI-O.


Pods


  • Definition: 
    • A pod is the smallest and simplest Kubernetes object. It represents a single instance of a running process in your cluster.
    • The smallest deployable units in Kubernetes, encapsulating one or more containers that share the same storage and network resources.
  • Components: 
    • Each pod contains one or more containers (usually Docker containers) that are tightly coupled and share the same network namespace and storage volumes.
  • Lifecycle: 
    • Pods are ephemeral. They are created, assigned a unique IP address, and scheduled on a node. If a pod dies, it won’t be resurrected; instead, a new pod will be created.
  • Use Case: 
    • Pods are used to run a single instance of an application or a part of an application. For example, a web server container and a helper container that pulls data from a database can run in the same pod.

Deploying containers on nodes by using a wrapper around one or more containers is what defines a pod. A pod is the smallest unit in Kubernetes that you can create or deploy. It represents a running process on your cluster as either a component of your application or an entire app. Generally, you only have one container per pod, but if you have multiple containers with a hard dependency, you can package them into a single pod and share networking and storage resources between them. The pod provides a unique network IP and set of ports for your containers, and configurable options that govern how your containers should run. 

One way to run a container in a pod in Kubernetes is to use the kubectl run command, which starts a deployment with a container running inside a pod. 


Services


  • Definition: 
    • A service is an abstraction that defines a logical set of pods and a policy by which to access them, such as a microservice within an application.
    • Abstract a logical set of pods and provide a stable endpoint for accessing these pods, facilitating load balancing and service discovery.
  • Components:
    • ClusterIP: Exposes the service on an internal IP in the cluster. This type makes the service only reachable from within the cluster.
    • NodePort: Exposes the service on the same port of each selected node in the cluster using NAT.
    • LoadBalancer: Exposes the service externally using a cloud provider’s load balancer.
    • Ingress
  • Use Case: 
    • Services provide a stable endpoint (IP and DNS name) for clients to access a set of pods. They handle load balancing and service discovery.

Kubernetes creates a service with a fixed IP address for our pods. And a controller says, I need to attach an external load balancer with a public IP address to that service so others outside the cluster can access it. 

In GKE, the load balancer is created as a network load balancer. Any client that reaches that IP address will be routed to a pod behind the service. 

A service is an abstraction which defines a logical set of pods and a policy by which to access them. As deployments create and destroy pods, pods will be assigned their own IP addresses, but those addresses don't remain stable over time. 

A service group is a set of pods and provides a stable endpoint or fixed IP address for them. For example, if you create two sets of pods called frontend and backend, and put them behind their own services, the backend pods might change, but frontend pods are not aware of this. They simply refer to the backend service. 

To scale a deployment run the kubectl scale command. In this example, three pods are created in your deployment, and they're placed behind the service and share one fixed IP address. You could also use autoscaling with other kinds of parameters. For example, you can specify that the number of pods should increase when CPU utilization reaches a certain limit. 

So far, we've seen how to run imperative commands like expose and scale. This works well to learn and test Kubernetes step by step. But the real strength of Kubernetes comes when you work in a declarative way. 

Instead of issuing commands, you provide a configuration file that tells Kubernetes what you want your desired state to look like, and Kubernetes determines how to do it. You accomplish this by using a deployment config file. You can check your deployment to make sure the proper number of replicas is running, by using either kubectl get deployments or kubectl describe deployments. To run five replicas instead of three, al you do is update the deployment config file and run the kubectl apply command to use the updated config file. 

You can still reach your endpoint as before by using kubectl get services to get the external IP of the service and reach the public IP address from a client. 

The last question is, what happens when you want to update a new version of your app? Well, you want to update your container to get new code in front of users, but rolling out all those changes at one time would be risky. So in this case, you would use kubectl rollout or change your deployment configuration file and then apply the change using kubectl apply. New pods will then be created according to your new update strategy. Here's an example configuration that will create new version pods individually and wait for a new pod to be available before destroying one of the old pods.


Deployments


  • Definition: 
    • A deployment provides declarative updates to applications. It describes an application’s lifecycle, such as which images to use for the app, the number of pod replicas, and how to update them.
    • Declarative updates to applications, managing the lifecycle of pods and ensuring the desired state is maintained.
  • Components:
    • ReplicaSet: Ensures a specified number of pod replicas are running at any given time. Deployments manage ReplicaSets.
    • Rolling Updates: Gradually replace instances of the old version of an application with a new version.
    • Rollback: Revert back to a previous version of the deployment if the current version is not stable.
  • Use Case: Deployments manage stateless applications. They ensure the desired state of an application is always maintained, handle scaling, and provide self-healing capabilities.

deployment represents a group of replicas of the same pod and keeps your pods running even when the nodes they run on fail. A deployment could represent a component of an application or even an entire app. 

To see a list of the running pods in your project, run the command, kubectl get pods


Architecture Overview


The Kubernetes architecture is designed for flexibility, scalability, and robustness:

  • Control Plane (Master Nodes):
    • Manages the entire cluster, scheduling workloads, and maintaining the desired state of the cluster.
  • Worker Nodes:
    • Run the application workloads, managing the lifecycle of pods based on the instructions from the control plane.

How a Kubernetes Cluster Works


  • User Interaction:
    • Users interact with the cluster via the Kubernetes API, typically using kubectl or other client tools.
  • API Server:
    • The API server processes requests, validates them, and updates the cluster state in etcd.
  • Scheduler:
    • The scheduler watches for newly created pods that do not have an assigned node, selecting nodes for them based on resource requirements.
  • Controller Manager:
    • Controllers constantly monitor the cluster state and make adjustments to ensure the desired state matches the current state.
  • Kubelet:
    • The kubelet on each worker node ensures the containers described in the pod specs are running and healthy.
  • Kube-proxy:
    • Manages network routing and load balancing to ensure seamless communication between pods and services.

Benefits of a Kubernetes Cluster


  • Scalability: Automatically scales applications up and down based on demand.
  • High Availability: Ensures application availability even if some nodes fail.
  • Resource Efficiency: Optimizes resource usage and balances workloads across nodes.
  • Flexibility: Supports a wide range of workloads, from microservices to batch processing.
  • Portability: Runs on various environments, including on-premises, cloud, and hybrid setups.

Wednesday, 24 April 2024

Installing Software on Linux

 


How to install software available in Package Repository?

Installing from Ubuntu Package Repository

Example: Installing VLC player

$ sudo apt-get update
$ sudo apt-get install vlc

It's best to run sudo apt-get update first as this updates local information about what packages are available from where in what versions. This can prevent a variety of installation errors (including some "unmet dependencies" errors), and also ensures you get the latest version provided by your enabled software sources.

There is also an apt version of this command:

sudo apt update
...
Reading package lists... Done
Building dependency tree       
Reading state information... Done
23 packages can be upgraded. Run 'apt list --upgradable' to see them.
...

To list all upgradable packages:

sudo apt list --upgradable

To upgrade all packages:

$ sudo apt upgrade

To see all installed packages:

$ sudo apt list --installed

To check if some package has already been installed:

$ sudo apt list --installed | grep package_name

...

If using Alpine distribution, you need to use apkComparison with other distros - Alpine Linux


Installing from non-default (3rd Party) Package Repository


Example: Installing PowerShell from Microsoft Package Repository

# Download the Microsoft repository GPG keys
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb

# Register the Microsoft repository GPG keys
sudo dpkg -i packages-microsoft-prod.deb

# Update the list of products
sudo apt-get update

# Enable the "universe" repositories
sudo add-apt-repository universe

# Install PowerShell
sudo apt-get install -y powershell

# Start PowerShell
pwsh


If you install the wrong version of packages-microsoft-prod.deb you can uninstall it with:

sudo dpkg -r packages-microsoft-prod
(Reading database ... 254902 files and directories currently installed.)
Removing packages-microsoft-prod (1.0-3) ...


How to install software distributed via Debian package (.deb) files?  


Installing the .deb package will automatically install the apt repository and signing key to enable auto-updating using the system's package manager. Alternatively, the repository and key can also be installed manually.

Some applications are not available in Debian Package Repository but can be downloaded as .deb files.

$ sudo dpkg -i /path/to/deb/file 
$ sudo apt-get install -f

The latter is necessary in order to fix broken packages (install eventual missing/unmet dependencies).

How to install a deb file, by dpkg -i or by apt?

Another example: Etcher

Debian and Ubuntu based Package Repository (GNU/Linux x86/x64)

Add Etcher debian repository:

echo "deb https://deb.etcher.io stable etcher" | sudo tee /etc/apt/sources.list.d/balena-etcher.list

Trust Bintray.com's GPG key:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61

Update and install:

sudo apt-get update
sudo apt-get install balena-etcher-electron

Uninstall

sudo apt-get remove balena-etcher-electron
sudo rm /etc/apt/sources.list.d/balena-etcher.list
sudo apt-get update


How to install applications distributed via snaps?

Snaps are containerised software packages. They're designed to install the programs within them on all major Linux systems without modification. Snaps do this by developers bundling a program's latest libraries in the containerized app.

Snap updates automatically and carries all its library dependencies, so is a better choice for users who want ease of deployment and to stay on top of the latest developments.

Snapcraft - Snaps are universal Linux packages

Installing snap on Ubuntu | Snapcraft documentation

How to Install and Use Snap on Ubuntu 18.04 - codeburst



Installing binaries


Some applications are distributed as binary files. We need to download them and set executable permissions. Instead of using cp and chmod commands, we can use install command which copies file to destination directory and automatically sets -rwxr-xr-x permissions over the file:

$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

$ sudo install minikube-linux-amd64 /usr/local/bin/minikube

$ ls -la /usr/local/bin/minikube
-rwxr-xr-x 1 root root 95637096 Apr 24 01:01 /usr/local/bin/minikube



We can pass to install command flags to set the owner and the group and also permission mode (as in chmod), instead of rwxr-xr-x:

$ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

0755 permissions mean the following: user can 7=read(4)+write(2)+execute(1); group can 5=read(4)+execute(1); anyone/world can 5=read(4)+execute(1) 

If you do not have root access on the target system, you can still install kubectl to the ~/.local/bin directory:

chmod +x kubectl
mkdir -p ~/.local/bin
mv ./kubectl ~/.local/bin/kubectl
# and then append (or prepend) ~/.local/bin to $PATH


It's worth noting here that install command can also just create a directory (all components of the path, like mkdir -p) and specify permissions on it:

$ install -m 0755 -d /etc/apt/keyrings


---

Thursday, 18 April 2024

Cron Utility (Unix)

cron command-line utility is a job scheduler on Unix-like operating systems. It runs as a daemon (background process).

These scheduled jobs (essentially a commands) are called cron jobs. They are repetitive tasks, scheduled to be run periodically, at certain time or interval.

Cron jobs, together with frequency and time of their execution are defined in cron table (crontab) file.
Each job is defined in its own line which has the following format:


minute (0–59)
# │ ┌───────────── hour (0–23)
# │ │ ┌───────────── day of the month (1–31)
# │ │ │ ┌───────────── month (1–12)
# │ │ │ │ ┌───────────── day of the week (0–6) (Sunday to Saturday;
# │ │ │ │ │                                   7 is also Sunday on some systems)
    *   *   *   *   *  <command to execute>


* means "every"

* * * * * = every minute, every hour, every day, every month
0 * * * * = every full hour, every day (HH:MM = *:0)
0 0 * * * = every midnight (HH:MM=0:0)
0 0 1 * * = once a month on the midnight of the first day of the month
0 10 * * * = every day at 10:00h
*/10 * * * * = every 10 minutes of every hour, every day


$ crontab
crontab: usage error: file name or - (for stdin) must be specified
Usage:
 crontab [options] file
 crontab [options]
 crontab -n [hostname]

Options:
 -u <user>  define user
 -e         edit user's crontab
 -l         list user's crontab
 -r         delete user's crontab
 -i         prompt before deleting
 -n <host>  set host in cluster to run users' crontabs
 -c         get host in cluster to run users' crontabs
 -T <file>  test a crontab file syntax
 -s         selinux context
 -V         print version and exit
 -x <mask>  enable debugging

Default operation is replace, per 1003.2


To list all cron jobs use:

$ crontab -l
* * * * * aws s3 sync ~/dir1/ s3://my-bucket/dir1 --region us-east-1 >> ~/logs/crons/s3_sync.log 2>&1
0 * * * * redis-cli -h redis-cache-group-123.cache.amazonaws.com -p 6345 flushall >> ~/logs/crons/flushRedisCache.log 2>&1
* * * * * ~/path/to/my_script1.sh >> ~/logs/crons/my_script1.sh.log 2>&1
0 0 * * * ~/path/to/my_script2.sh >> ~/logs/crons/my_script2.log 2>&1
0 0 1 * * ~/path/to/my_script3.sh >> ~/logs/crons/my_script3.log 2>&1
0 10 * * * ~/path/to/my_script4.sh >> ~/logs/crons/my_script4.log 2>&1
*/10 * * * * rsync -avhl --delete ~/path/to/source ~/path/to/dest/ >> ~/logs/crons/source_dest_rsync.log 2>&1

crontab file should not be edited with file editors but via crontab:

crontab -l


How to disable some cron job?


Simply comment its line in crontab with #.

How to disable all cron jobs?

Either comment all lines in crontab or 

$ crontab -l > crontab_backup.txt
$ crontab -r


-r = removes the current crontab 

To restore backup crontab:

$ crontab crontab_backup.txt
$ crontab -l


Resources:

cron - Wikipedia

Thursday, 11 April 2024

Docker Interview Questions

Here are some Docker Interview Questions with answers and/or links to answers. Good luck! 💪🤞





Kubernetes Interview Questions

Here are some Kubernetes interview questions. Good Luck!



Git Interview Questions



  • What is Git?
  • Explain git clone command.
  • Explain git checkout command.
  • What is cherry picking?
    • When to use it? (explain how it's used for team collaboration, bug hotfixes, ...)
    • What is the syntax of git cherry pick command?
    • On which branch do we need to be before cherry picking?
    • How does the commit graph look like before and after cherry picking? (draw an example)
    • Explain its options:
      • -edit
      • --no-commit
    • Git Cherry Pick | Atlassian Git Tutorial
  • Explain git log command
  • What is the difference between git revert and reset commands. Which one should be used on public branches?
  • To Be Continued...

Python Interview Questions

Here are some Python interview questions. Good luck!



  • What does the following expression do? if __name__ == "__main__"
    • https://stackoverflow.com/questions/419163/what-does-if-name-main-do

More questions:

DevOps Interview Questions

Here are some general DevOps interview questions. Good luck!

image source: What is DevOps?



Terraform Interview Questions

Here are some Terraform Interview Questions with answers and/or links to answers. Good luck!


Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # site24x7_website_monitor.this["my_services_monitors"] has been changed
  ~ resource "site24x7_website_monitor" "this" {
      - auth_user                   = "pingdom" -> null
        id                          = "405565000027631014"
      ~ ignore_cert_err             = true -> false
        # (29 unchanged attributes hidden)
    }
  # site24x7_website_monitor.this["my_vpn_center_licensing"] has been changed
  ~ resource "site24x7_website_monitor" "this" {
        id                          = "405565000027631133"
      ~ ignore_cert_err             = true -> false
        # (29 unchanged attributes hidden)
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.

jsonencode encodes a given value to a string using JSON syntax. So string will be transformed into a string:

> jsonencode("{\"name\":\"Bojan\"}")
"\"{\\\"name\\\":\\\"Bojan\\\"}\""

So escape character got escaped...and that's still a valid JSON (try it here: https://jsonlint.com/)

We usually want to JSON-stringify an object, not a string:

> jsonencode({"name":"Bojan"})
"{\"name\":\"Bojan\"}"


This is why, for example, we don't want to call jsonencode(templatefile(file.tftpl, {...})) but vice versa:
templatefile(jsonencode(file.tftpl), {...}). Even better, file.tftpl can be an interpolation of the jsonencode call against the real json content: ${jsonencode({...})}. 


Resources:


https://github.com/nnellans/terraform-guide