mirror of
https://github.com/bregman-arie/devops-exercises.git
synced 2024-11-19 20:31:47 +02:00
Add Terraform questions
Terraform also deserves some attention.
This commit is contained in:
parent
4f73d7e140
commit
db7ff1dc93
2
faq.md
2
faq.md
@ -9,7 +9,7 @@ Learning, of course.
|
||||
### My goal is to prepare for a DevOps interviews. Should I use this repository?
|
||||
|
||||
Overall, this repository should help you learn some concepts but, don't assume at any point that your interview will include similar questions to those that included in this repository.
|
||||
Regarding interview, I've added a couple of suggestions [here](prepare_for_interview.md)<br>
|
||||
Regarding interviews, I've added a couple of suggestions [here](prepare_for_interview.md)<br>
|
||||
|
||||
### Will you stop at some point adding questions and exercises?
|
||||
|
||||
|
@ -6,15 +6,15 @@ Note: the following is opinionated.
|
||||
|
||||
#### Linux
|
||||
|
||||
Every DevOps Engineer should have a deep understanding of at least one operating system and if you have the option to choose then I would say it should definitely be Linux as I believe it's a requirement of at least 90% of the DevOps jobs postings out there.
|
||||
Every DevOps Engineer should have a deep understanding of at least one operating system and if you have the option to choose then I would say it should definitely be Linux as I believe it's a requirement of at least 90% of the DevOps jobs postings out there. In addition, Linux is almost integral part of any sub-area or domain in DevOps like Cloud, Containers, etc.
|
||||
|
||||
Usually, the followup question is "How extensive should my knowledge be?" Out of all the DevOps skills, I would say this, along with coding, should be your strongest skills. Be familiar with OS processes, debugging tools, filesystem, networking, ... know your operating system, understand how it works, how to manage issues, etc.
|
||||
Usually, the followup question is "How extensive should my knowledge be?" Out of all the DevOps skills, I would say this, along with coding, should be your strongest skills. Be familiar with OS processes, debugging tools, filesystem, networking, ... know your operating system, understand how it works, how to troubleshoot issues, etc.
|
||||
|
||||
Not long ago, I've created a list of Linux resources right [here](https://dev.to/abregman/collection-of-linux-resources-3nhk). There are some good sites there that you can use for learning more about Linux.
|
||||
|
||||
#### Programming
|
||||
|
||||
My personal belief is that any DevOps engineer should know programming, at least to some degree. Having this skill you can automate manual processes, improve some of the open source tools you are using today or build new tools & projects to provide a solution to existing problems. Knowing how to code = a lot of power.
|
||||
My personal belief is that any DevOps engineer should know programming, at least to some degree. Having this skill you can automate manual processes, improve some of the open source tools you are using today or build new tools & projects to provide a solution to existing problems. Knowing how to code = a lot of power.
|
||||
|
||||
When it comes to interviews you'll notice that the level of knowledge very much depends on the company or position you are interviewing for. Some will require you just to be able to write simple scripts while others will deep dive into complex algorithms and data structures.
|
||||
|
||||
@ -39,19 +39,18 @@ Some ideas for you to explore:
|
||||
* How to design and implement a CI pipeline (or pipelines) for verifying PRs, run multiple different types of tests, package the project and deploy it somewhere
|
||||
* How to design and implement secured ELK architecture which will get logs from 10,000 apps and will display the data eventually to the user
|
||||
* Microservices designs are also quite popular these days
|
||||
|
||||
I recommend going over the following GitHub projects as they are really deep-diving into System Design:
|
||||
|
||||
* https://github.com/donnemartin/system-design-primer
|
||||
|
||||
#### Tools
|
||||
|
||||
|
||||
In general, you should be able to describe some designs, projects, architectures, ... you performed.
|
||||
|
||||
#### Tooling
|
||||
|
||||
Some interviews will focus on specific tools or technologies. Which tools? this is mainly based on a combination of what you mentioned in your C.V & those that are mentioned in the job posting and used in the company. Here are some questions I believe anyone should know to answer regarding the tools he/she is familiar with:
|
||||
|
||||
* What the tool does? What it allows us to achieve that we couldn't do without it?
|
||||
* What its advantages over other tools in the same area, with the same purpose? Why you specifically using it?
|
||||
* How it works?
|
||||
* How to use it?
|
||||
* How it works?
|
||||
* How to use it?
|
||||
* Best practices you apply/use when using it
|
||||
|
||||
Let's deep dive into practical preparation steps
|
||||
|
||||
@ -65,12 +64,11 @@ This is a great way to prepare for interviews and I recommend to try it out befo
|
||||
|
||||
At this point, some people ask: "but what project?" and the answer is: what about GitHub? it has only 9125912851285192 projects...and a free way to set up CI to any of them (also a great way to learn how to collaborate with others :) )
|
||||
|
||||
Let's convert another scenario:
|
||||
|
||||
Let's convert another scenario:
|
||||
|
||||
"Experience with provisioning servers" -> Scenario: provision a server (to make it more interesting: create a web server).
|
||||
|
||||
And the last example:
|
||||
|
||||
"Experience with scripting" -> Scenario: write a script. Don't waste too much time thinking "what script should I write?". Simply automate something you are doing manually or even implement your own version of common small utils.
|
||||
|
||||
### Start your own DevOps project
|
||||
@ -102,7 +100,6 @@ Doing so can give you a lot of information on what to expect from an interview a
|
||||
It may sound trivial but the idea here is simple: be ready to answer any question regarding any line you included in your resume.
|
||||
Sometimes candidates surprised when they are asked on a skill or line which seems to be not related to the position but the simple truth is: if you mentioned something on your resume, it's only fair to ask you about it.
|
||||
|
||||
|
||||
### Know the company
|
||||
|
||||
Be familiar with the company you are interviewing at. Some ideas:
|
||||
@ -115,7 +112,7 @@ Be familiar with the company you are interviewing at. Some ideas:
|
||||
|
||||
From my experience, this is not done by many candidates but it's one of the best ways to deep dive into topics like operating system, virtualization, scale, distributed systems, etc.
|
||||
|
||||
In most cases, you will do fine without reading books but for the AAA interviews (hardest level) you'll want to read some books and overall if you inspire to be better DevOps Engineer, books (also articles, blog posts) is a great way :)
|
||||
In most cases, you will do fine without reading books but for the AAA interviews (hardest level) you'll want to read some books and overall if you inspire to be better DevOps Engineer, books (also articles, blog posts) is a great way devleop yourself :)
|
||||
|
||||
### Consider starting in non-DevOps position
|
||||
|
||||
@ -147,7 +144,6 @@ the company he/she is interviewing at, is the right place for him/her.
|
||||
* Do I care about work-life balance?
|
||||
* Do I care about personal growth and how it's practically done?
|
||||
* Do I care about knowing what are my responsibilities as part of the role?
|
||||
|
||||
If you do, you should also play the interviewer role :)
|
||||
|
||||
### One Last Thing
|
||||
|
@ -7,12 +7,15 @@
|
||||
- [Questions](#questions)
|
||||
- [Terraform 101](#terraform-101-1)
|
||||
- [Terraform Hands-On Basics](#terraform-hands-on-basics)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Providers](#providers)
|
||||
- [Provisioners](#provisioners)
|
||||
- [Modules](#modules)
|
||||
- [Variables](#variables)
|
||||
- [Variables Hands-On](#variables-hands-on)
|
||||
- [State](#state)
|
||||
- [Import](#import)
|
||||
- [Version Control](#version-control)
|
||||
- [AWS](#aws-1)
|
||||
|
||||
## Exercises
|
||||
@ -103,9 +106,98 @@ To be clear, CM tools can be used to provision resources so in the end goal of h
|
||||
### Terraform Hands-On Basics
|
||||
|
||||
<details>
|
||||
<summary>How to reference other parts of your Terraform code?</summary><br><b>
|
||||
<summary>Explain the following block of Terraform code
|
||||
|
||||
```
|
||||
resource "aws_instance" "some-instance" {
|
||||
ami = "ami-201720221991yay"
|
||||
instance_type = "t2.micro
|
||||
}
|
||||
```
|
||||
</summary><br><b>
|
||||
|
||||
It's a resource of type "aws_instance" used to provision an instance. The name of the resource (NOT INSTANCE) is "some-instance".
|
||||
|
||||
The instance itself will be provisioned with type "t2.micro" and using an image of the AMI "ami-201720221991yay".
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What do you do next after writing the following in main.tf file?
|
||||
|
||||
```
|
||||
resource "aws_instance" "some-instance" {
|
||||
ami = "ami-201720221991yay"
|
||||
instance_type = "t2.micro
|
||||
}
|
||||
```
|
||||
</summary><br><b>
|
||||
|
||||
Run `terraform init`. This will scan the code in the directory to figure out which providers are used (in this case AWS provider) and will download them
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You've executed <code>terraform init</code> and now you would like to move forward to creating the resources but you have concerns and would like to make be 100% sure on what you are going to execute. What should you be doing?</summary><br><b>
|
||||
|
||||
Execute `terraform plan`. That will provide a detailed information on what Terraform will do once you apply the changes.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You've downloaded the providers, seen the what Terraform will do (with terraform plan) and you are ready to actually apply the changes. What should you do next?</summary><br><b>
|
||||
|
||||
Run `terraform apply`. That will apply the changes described in your .tf files.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain the meaning of the following strings that seen at the beginning of each line When you run <code>terraform apply</code>
|
||||
|
||||
* '+'
|
||||
* '-'
|
||||
* '-/+'
|
||||
</summary><br><b>
|
||||
|
||||
* '+' - The resource or attribute is going to be added
|
||||
* '-' - the resource or attribute is going to be removed
|
||||
* '-/+' - the resource or attribute is going to be replaced
|
||||
</b></details>
|
||||
|
||||
### Dependencies
|
||||
|
||||
<details>
|
||||
<summary>Sometimes you need to reference some resources in the same or separate .tf file. Why and how it's done?</summary><br><b>
|
||||
|
||||
Why: because resources are sometimes connected or need to be connected. For example, you create an AWS instance with "aws_instance" resource but, at the same time you would like also to allow some traffic to it (because by default traffic is not allowed). For that you'll create a "aws_security_group" resource and then, in your aws_instance resource, you'll reference it.
|
||||
|
||||
How:
|
||||
|
||||
Using the syntax <PROVIDER TYPE>.<NAME>.<ATTRIBUTE>
|
||||
|
||||
In your AWS instance it would like that:
|
||||
|
||||
```
|
||||
resource "aws_instance" "some-instance" {
|
||||
|
||||
ami = "some-ami"
|
||||
instance_type = "t2.micro"
|
||||
vpc_security_group_ids = [aws_security_group.instance.id]
|
||||
|
||||
}
|
||||
```
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Does it matter in which order Terraform creates resources?</summary><br><b>
|
||||
|
||||
Yes, when there is a dependency between different Terraform resources, you want the resources to be created in the right order and this is exactly what Terraform does.
|
||||
|
||||
To make it ever more clear, if you have a resource X that references the ID of resource Y, it doesn't makes sense to create first resource X because it won't have any ID to get from a resource that wasn't created yet.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Is there a way to print/see the dependencies between the different resources?</summary><br><b>
|
||||
|
||||
Yes, with `terraform graph`
|
||||
|
||||
The output is in DOT - A graph description language.
|
||||
</b></details>
|
||||
|
||||
### Providers
|
||||
@ -192,6 +284,12 @@ By default Terraform providers are installed from Terraform Registry
|
||||
The Terraform Registry provides a centralized location for official and community-managed providers and modules.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Where providers are downloaded to? (when for example you run <code>terraform init</code>)</summary><br><b>
|
||||
|
||||
`.terraform` directory.
|
||||
</b></details>
|
||||
|
||||
### Provisioners
|
||||
|
||||
<details>
|
||||
@ -317,9 +415,16 @@ You might have a different opinion but my personal take on that, is to keep modu
|
||||
|
||||
### Variables
|
||||
|
||||
<details>
|
||||
<summary>What variables are good for in Terraform?</summary><br><b>
|
||||
|
||||
Variables allow you define piece of data in one location instead of repeating the hardcoded value of it in multiple different locations. Then when you need to modify the variable's value, you do it in one location instead of changing each one of the hardcoded values.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What types of variables are supported in Terraform?</summary><br><b>
|
||||
|
||||
```
|
||||
string
|
||||
number
|
||||
bool
|
||||
@ -328,56 +433,29 @@ set(<TYPE>)
|
||||
map(<TYPE>)
|
||||
object({<ATTR_NAME> = <TYPE>, ... })
|
||||
tuple([<TYPE>, ...])
|
||||
```
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What are Input Variables in Terraform? Why one should use them?</summary><br><b>
|
||||
<summary>What's the default variable type in Terraform?</summary><br><b>
|
||||
|
||||
Input variables serve as parameters to the module in Terraform. They allow you for example to define once the value of a variable and use that variable in different places in the module so next time you would want to change the value, you will change it in one place instead of changing the value in different places in the module.
|
||||
`any`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to define variables?</summary><br><b>
|
||||
<summary>What ways are there to pass values for variables?</summary><br><b>
|
||||
|
||||
```
|
||||
variable "app_id" {
|
||||
type = string
|
||||
description = "The id of application"
|
||||
default = "some_value"
|
||||
}
|
||||
```
|
||||
* Using `-var` option in the CLI
|
||||
* Using a file by using the `-var-file` option in the CLI
|
||||
* Environment variable that starts with `TF_VAR_<VAR_NAME>`
|
||||
|
||||
Usually they are defined in their own file (vars.tf for example).
|
||||
If no value given, user will be prompted to provide one.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How variables are used in modules?</summary><br><b>
|
||||
<summary>How to reference variable?</summary><br><b>
|
||||
|
||||
They are referenced with `var.VARIABLE_NAME`
|
||||
|
||||
vars.tf:
|
||||
|
||||
```
|
||||
variable "memory" {
|
||||
type = string
|
||||
default "8192"
|
||||
}
|
||||
|
||||
variable "cpu" {
|
||||
type = string
|
||||
default = "4"
|
||||
}
|
||||
```
|
||||
|
||||
main.tf:
|
||||
|
||||
```
|
||||
resource "libvirt_domain" "vm1" {
|
||||
name = "vm1"
|
||||
memory = var.memory
|
||||
cpu = var.cpu
|
||||
}
|
||||
```
|
||||
Using the syntax `var.<VAR_NAME>`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -413,9 +491,9 @@ True
|
||||
<details>
|
||||
<summary>The same variable is defined in the following places:
|
||||
|
||||
- The file `terraform.tfvars`
|
||||
- Environment variable
|
||||
- Using `-var` or `-var-file`
|
||||
- The file `terraform.tfvars`
|
||||
- Environment variable
|
||||
- Using `-var` or `-var-file`
|
||||
|
||||
According to variable precedence, which source will be used first?</summary><br><b>
|
||||
|
||||
@ -424,17 +502,110 @@ The order is:
|
||||
- Environment variable
|
||||
- The file `terraform.tfvars`
|
||||
- Using `-var` or `-var-file`
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What other way is there to define lots of variables in more "simplified" way?</summary><br><b>
|
||||
<summary>Whenever you run terraform apply, it prompts to enter a value for a given variable. How to avoid being prompted?</summary><br><b>
|
||||
|
||||
Using `.tfvars` file which contains variable consists of simple variable names assignments this way:
|
||||
While removing the variable is theoretically a correct answer, it will probably fail the execution.
|
||||
|
||||
You can use something like the `-var` option to provide the value and avoid being prompted to insert a value. Another option is to run `export TF_VAR_<VAR_NAME>=<VALUE>`.
|
||||
|
||||
</b></details>
|
||||
|
||||
#### Variables Hands-On
|
||||
|
||||
<details>
|
||||
<summary>Demonstrate variable definition with type, description and default parameters</summary><br><b>
|
||||
|
||||
```
|
||||
x = 2
|
||||
y = "mario"
|
||||
z = "luigi"
|
||||
variable "app_id" {
|
||||
type = string
|
||||
description = "The id of application"
|
||||
default = "some_value"
|
||||
}
|
||||
```
|
||||
|
||||
Unrelated note: variables are usually defined in their own file (vars.tf for example).
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to define a variable which is a list of numbers?</summary><br><b>
|
||||
|
||||
```
|
||||
variable "list_of_nums" {
|
||||
type = list(number)
|
||||
description = "An example of list of numbers"
|
||||
default = [2, 0, 1, 7]
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to define a variable which is an object with attributes "model" (string), "color" (string), year (number)?</summary><br><b>
|
||||
|
||||
```
|
||||
variable "car_model" {
|
||||
description = "Car model object"
|
||||
type = object({
|
||||
model = string
|
||||
color = string
|
||||
year = number
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Note: you can also define a default for it.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to reference variables?</summary><br><b>
|
||||
|
||||
Variable are referenced with `var.VARIABLE_NAME` syntax. Let's have a look at an example:
|
||||
|
||||
vars.tf:
|
||||
|
||||
```
|
||||
variable "memory" {
|
||||
type = string
|
||||
default "8192"
|
||||
}
|
||||
|
||||
variable "cpu" {
|
||||
type = string
|
||||
default = "4"
|
||||
}
|
||||
```
|
||||
|
||||
main.tf:
|
||||
|
||||
```
|
||||
resource "libvirt_domain" "vm1" {
|
||||
name = "vm1"
|
||||
memory = var.memory
|
||||
cpu = var.cpu
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to reference variable from inside of string literal? (bonus question: how that type of expression is called?)</summary><br><b>
|
||||
|
||||
Using the syntax: `"${var.VAR_NAME}"`. It's called "interpolation".
|
||||
|
||||
Very common to see it used in user_data attribute related to instances.
|
||||
|
||||
```
|
||||
user_data = <<-EOF
|
||||
This is some fabulos string
|
||||
It demonstrates how to use interpolation
|
||||
Yes, it's truly ${var.awesome_or_meh}
|
||||
EOF
|
||||
```
|
||||
</b></details>
|
||||
|
||||
@ -444,30 +615,35 @@ z = "luigi"
|
||||
<summary>What's Terraform State?</summary><br><b>
|
||||
|
||||
[Terraform.io](https://www.terraform.io/language/state): "Terraform must store state about your managed infrastructure and configuration. This state is used by Terraform to map real world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures."
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What <code>terraform.tfstate</code> file is used for?</summary><br><b>
|
||||
|
||||
It keeps track of the IDs of created resources so that Terraform knows what it's managing.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to inspect current state?</summary><br><b>
|
||||
|
||||
terraform show
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to list resources created with Terraform?</summary><br><b>
|
||||
|
||||
terraform state list
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How do you rename an existing resource?</summary><br><b>
|
||||
|
||||
terraform state mv
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -478,6 +654,7 @@ terraform state mv
|
||||
- tfstate is in important file. As such, it might be better to put it in a location that has regular backups.
|
||||
|
||||
As such, tfstate shouldn't be stored in git repositories. secured storage such as secured buckets, is a better option.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -485,24 +662,28 @@ As such, tfstate shouldn't be stored in git repositories. secured storage such a
|
||||
|
||||
- terraform apply file.terraform
|
||||
- Above command will create tfstate file in the working folder.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>By default where does the state get stored?</summary><br><b>
|
||||
|
||||
- The state is stored by default in a local file named terraform.tfstate.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What is Terraform import?</summary><br><b>
|
||||
|
||||
Terraform import is used to import existing infrastructure. It allows you to bring resources created by some other means (eg. manually launched cloud resources) and bring it under Terraform management.
|
||||
Terraform import is used to import existing infrastructure. It allows you to bring resources created by some other means (eg. manually launched cloud resources) and bring it under Terraform management.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Can we store tfstate file at remote location? If yes, then in which condition you will do this?</summary><br><b>
|
||||
|
||||
- Yes, It can also be stored remotely, which works better in a team environment. Given condition that remote location is not publicly accessible since tfstate file contain sensitive information as well. Access to this remote location must be only shared with team members.
|
||||
Yes, It can also be stored remotely, which works better in a team environment. Given condition that remote location is not publicly accessible since tfstate file contain sensitive information as well. Access to this remote location must be only shared with team members.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -513,6 +694,7 @@ Terraform import is used to import existing infrastructure. It allows you to bri
|
||||
- Backup it regularly so you can roll-back easily when needed
|
||||
- Store it in remote shared storage. This is especially needed when working in a team and the state can be updated by any of the team members
|
||||
- Enabled versioning if the storage where you store the state file, supports it. Versioning is great for backups and roll-backs in case of an issue.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -558,6 +740,20 @@ It's does NOT create the definitions/configuration for creating such infrastruct
|
||||
2. You lost your tfstate file and need to rebuild it
|
||||
</b></details>
|
||||
|
||||
### Version Control
|
||||
|
||||
<details>
|
||||
<summary>You have a Git repository with Terraform files but no .gitignore. What would you add to a .gitignore file in Terraform repository?</summary><br><b>
|
||||
|
||||
```
|
||||
.terraform
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
```
|
||||
|
||||
You don't want to store state file nor any downloaded providers in .terraform directory. It also doesn't makes sense to share/store the state backup files.
|
||||
</b></details>
|
||||
|
||||
### AWS
|
||||
|
||||
<details>
|
||||
|
Loading…
Reference in New Issue
Block a user