Compare commits
9 Commits
21a70c3542
...
ad12a30dae
Author | SHA1 | Date | |
---|---|---|---|
|
ad12a30dae | ||
|
21206e761e | ||
|
4fbe045844 | ||
|
9435ed4125 | ||
|
3d161adce3 | ||
|
066a273cd2 | ||
|
252c66fc1f | ||
|
ad208750fa | ||
|
2eed0da5d9 |
@ -1,5 +1,6 @@
|
||||
# DevOps 面试问题
|
||||
|
||||
<!-- {% raw %} -->
|
||||
|
||||
:information_source: 本仓库包含各种 DevOps 相关主题的面试问题
|
||||
|
||||
@ -1273,7 +1274,7 @@ The content of the system_info.j2 template
|
||||
|
||||
```
|
||||
# {{ ansible_managed }}
|
||||
I'm {{ ansible_hostname }} and my operating system is {{ ansible_distribution }
|
||||
I'm {{ ansible_hostname }} and my operating system is {{ ansible_distribution }}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
@ -2981,4 +2982,6 @@ where c.Customer_ID in (Select Customer_ID from cat_food);
|
||||
* [Ansible, Minikube and Docker](scenarios/ansible_minikube_docker.md)
|
||||
* [Cloud Slack bot](scenarios/cloud_slack_bot.md)
|
||||
* [Writing Jenkins Scripts](scenarios/jenkins_scripts.md)
|
||||
* [Writing Jenkins Pipelines](scenarios/jenkins_pipelines.md)
|
||||
* [Writing Jenkins Pipelines](scenarios/jenkins_pipelines.md)
|
||||
|
||||
<!-- {% endraw %} -->
|
50
README.md
50
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
:information_source: This repo contains questions and exercises on various technical topics, sometimes related to DevOps and SRE
|
||||
|
||||
:bar_chart: There are currently **2590** exercises and questions
|
||||
:bar_chart: There are currently **2619** exercises and questions
|
||||
|
||||
:warning: You can use these for preparing for an interview but most of the questions and exercises don't represent an actual interview. Please read [FAQ page](faq.md) for more details
|
||||
|
||||
@ -18,27 +18,27 @@
|
||||
<center>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/devops/README.md"><img src="images/devops.png" width="75px;" height="75px;" alt="DevOps" /><br /><b>DevOps</b></a></td>
|
||||
<td align="center"><a href="topics/cicd/README.md"><img src="images/cicd.png" width="75px;" height="75px;" alt="cicd"/><br /><b>CI/CD</b></a></td>
|
||||
<td align="center"><a href="topics/git/README.md"><img src="images/git.png" width="75px;" height="75px;" alt="Git"/><br /><b>Git</b></a></td>
|
||||
<td align="center"><a href="topics/ansible/README.md"><img src="images/ansible.png" width="75px;" height="75px;" alt="ansible"/><br /><b>Ansible</b></a></td>
|
||||
<td align="center"><a href="topics/devops"><img src="images/devops.png" width="75px;" height="75px;" alt="DevOps" /><br /><b>DevOps</b></a></td>
|
||||
<td align="center"><a href="topics/cicd"><img src="images/cicd.png" width="75px;" height="75px;" alt="cicd"/><br /><b>CI/CD</b></a></td>
|
||||
<td align="center"><a href="topics/git"><img src="images/git.png" width="75px;" height="75px;" alt="Git"/><br /><b>Git</b></a></td>
|
||||
<td align="center"><a href="topics/ansible"><img src="images/ansible.png" width="75px;" height="75px;" alt="ansible"/><br /><b>Ansible</b></a></td>
|
||||
<td align="center"><a href="#network"><img src="images/network.png" width="75px;" height="75px;" alt="Network"/><br /><b>Network</b></a></td>
|
||||
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/software_development/README.md"><img src="images/programming.png" width="75px;" height="75px;" alt="programming"/><br /><b>Software Development</b></a></td>
|
||||
<td align="center"><a href="topics/software_development"><img src="images/programming.png" width="75px;" height="75px;" alt="programming"/><br /><b>Software Development</b></a></td>
|
||||
<td align="center"><a href="https://github.com/bregman-arie/python-exercises"><img src="images/python.png" width="75px;" height="75px;" alt="Python"/><br /><b>Python</b></a></td>
|
||||
<td align="center"><a href="https://github.com/bregman-arie/go-exercises"><img src="images/Go.png" width="75px;" height="75px;" alt="go"/><br /><b>Go</b></a></td>
|
||||
<td align="center"><a href="topics/shell/README.md"><img src="images/bash.png" width="75px;" height="75px;" alt="Bash"/><br /><b>Shell Scripting</b></a></td>
|
||||
<td align="center"><a href="topics/kubernetes/README.md"><img src="images/kubernetes.png" width="75px;" height="75px;" alt="kubernetes"/><br /><b>Kubernetes</b></a></td>
|
||||
<td align="center"><a href="topics/shell"><img src="images/bash.png" width="75px;" height="75px;" alt="Bash"/><br /><b>Shell Scripting</b></a></td>
|
||||
<td align="center"><a href="topics/kubernetes"><img src="images/kubernetes.png" width="75px;" height="75px;" alt="kubernetes"/><br /><b>Kubernetes</b></a></td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/cloud/README.md"><img src="images/cloud.png" width="75px;" height="75px;" alt="Cloud"/><br /><b>Cloud</b></a></td>
|
||||
<td align="center"><a href="topics/aws/README.md"><img src="images/aws.png" width="100px;" height="75px;" alt="aws"/><br /><b>AWS</b></a></td>
|
||||
<td align="center"><a href="topics/azure/README.md"><img src="images/azure.png" width="75px;" height="75px;" alt="azure"/><br /><b>Azure</b></a></td>
|
||||
<td align="center"><a href="topics/gcp/README.md"><img src="images/googlecloud.png" width="70px;" height="70px;" alt="Google Cloud Platform"/><br /><b>Google Cloud Platform</b></a></td>
|
||||
<td align="center"><a href="topics/cloud"><img src="images/cloud.png" width="75px;" height="75px;" alt="Cloud"/><br /><b>Cloud</b></a></td>
|
||||
<td align="center"><a href="topics/aws"><img src="images/aws.png" width="100px;" height="75px;" alt="aws"/><br /><b>AWS</b></a></td>
|
||||
<td align="center"><a href="topics/azure"><img src="images/azure.png" width="75px;" height="75px;" alt="azure"/><br /><b>Azure</b></a></td>
|
||||
<td align="center"><a href="topics/gcp"><img src="images/googlecloud.png" width="70px;" height="70px;" alt="Google Cloud Platform"/><br /><b>Google Cloud Platform</b></a></td>
|
||||
<td align="center"><a href="#openstack"><img src="images/openstack.png" width="75px;" height="75px;" alt="openstack"/><br /><b>OpenStack</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -46,7 +46,7 @@
|
||||
<td align="center"><a href="#monitoring"><img src="images/monitoring.png" width="75px;" height="75px;" alt="Monitoring"/><br /><b>Monitoring</b></a></td>
|
||||
<td align="center"><a href="#elastic"><img src="images/elastic.png" width="75px;" height="75px;" alt="Elastic"/><br /><b>Elastic</b></a></td>
|
||||
<td align="center"><a href="#virtualization"><img src="images/virtualization.png" width="75px;" height="75px;" alt="Virtualization"/><br /><b>Virtualization</b></a></td>
|
||||
<td align="center"><a href="topics/dns/README.md"><img src="images/dns.png" width="75px;" height="75px;" alt="DNS"/><br /><b>DNS</b></a></td>
|
||||
<td align="center"><a href="topics/dns"><img src="images/dns.png" width="75px;" height="75px;" alt="DNS"/><br /><b>DNS</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="#testing"><img src="images/testing.png" width="75px;" height="75px;" alt="Testing"/><br /><b>Testing</b></a></td>
|
||||
@ -57,34 +57,34 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="#certificates"><img src="images/certificates.png" width="75px;" height="75px;" alt="Certificates"/><br /><b>Certificates</b></a></td>
|
||||
<td align="center"><a href="topics/containers/README.md"><img src="images/containers.png" width="75px;" height="75px;" alt="Containers"/><br /><b>Containers</b></a></td>
|
||||
<td align="center"><a href="topics/containers"><img src="images/containers.png" width="75px;" height="75px;" alt="Containers"/><br /><b>Containers</b></a></td>
|
||||
<td align="center"><a href="#sql"><img src="images/sql.png" width="75px;" height="75px;" alt="sql"/><br /><b>SQL</b></a></td>
|
||||
<td align="center"><a href="topics/openshift/README.md"><img src="images/openshift.png" width="75px;" height="75px;" alt="OpenShift"/><br /><b>OpenShift</b></a></td>
|
||||
<td align="center"><a href="topics/openshift"><img src="images/openshift.png" width="75px;" height="75px;" alt="OpenShift"/><br /><b>OpenShift</b></a></td>
|
||||
<td align="center"><a href="#storage"><img src="images/storage.png" width="75px;" height="75px;" alt="Storage"/><br /><b>Storage</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/terraform/README.md"><img src="images/terraform.png" width="75px;" height="75px;" alt="Terraform"/><br /><b>Terraform</b></a></td>
|
||||
<td align="center"><a href="topics/terraform"><img src="images/terraform.png" width="75px;" height="75px;" alt="Terraform"/><br /><b>Terraform</b></a></td>
|
||||
<td align="center"><a href="#mongo"><img src="images/mongo.png" width="75px;" height="75px;" alt="Mongo"/><br /><b>Mongo</b></a></td>
|
||||
<td align="center"><a href="#puppet"><img src="images/puppet.png" width="75px;" height="75px;" alt="puppet"/><br /><b>Puppet</b></a></td>
|
||||
<td align="center"><a href="#distributed"><img src="images/distributed.png" width="75px;" height="75px;" alt="Distributed"/><br /><b>Distributed</b></a></td>
|
||||
<td align="center"><a href="#questions-you-ask"><img src="images/you.png" width="75px;" height="75px;" alt="you"/><br /><b>Questions you can ask</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/circleci/README.md"><img src="images/logos/circleci.png" width="70px;" height="70px;" alt="Circle CI"/><br /><b>Circle CI</b></a></td>
|
||||
<td align="center"><a href="topics/argo/README.md"><img src="images/logos/argo.png" width="80px;" height="80px;" alt="Argo"/><br /><b>Argo</b></a></td>
|
||||
<td align="center"><a href="topics/kafka/README.md"><img src="images/logos/kafka.png" width="85px;" height="80px;" alt="Kafka"/><br /><b>Kafka</b></a></td>
|
||||
<td align="center"><a href="topics/datadog/README.md"><img src="images/logos/datadog.png" width="80px;" height="80px;" alt="DataDog"/><br /><b></b></a></td>
|
||||
<td align="center"><a href="topics/perl/README.md"><img src="images/perl.png" width="75px;" height="75px;" alt="perl"/><br /><b>Perl</b></a></td>
|
||||
<td align="center"><a href="topics/circleci"><img src="images/logos/circleci.png" width="70px;" height="70px;" alt="Circle CI"/><br /><b>Circle CI</b></a></td>
|
||||
<td align="center"><a href="topics/argo"><img src="images/logos/argo.png" width="80px;" height="80px;" alt="Argo"/><br /><b>Argo</b></a></td>
|
||||
<td align="center"><a href="topics/kafka"><img src="images/logos/kafka.png" width="85px;" height="80px;" alt="Kafka"/><br /><b>Kafka</b></a></td>
|
||||
<td align="center"><a href="topics/datadog"><img src="images/logos/datadog.png" width="80px;" height="80px;" alt="DataDog"/><br /><b></b></a></td>
|
||||
<td align="center"><a href="topics/perl"><img src="images/perl.png" width="75px;" height="75px;" alt="perl"/><br /><b>Perl</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/linux/README.md"><img src="images/logos/linux.png" width="75px;" height="75px;" alt="Linux"/><br /><b>Linux</b></a></td>
|
||||
<td align="center"><a href="topics/linux"><img src="images/logos/linux.png" width="75px;" height="75px;" alt="Linux"/><br /><b>Linux</b></a></td>
|
||||
<td align="center"><a href="#prometheus"><img src="images/prometheus.png" width="75px;" height="75px;" alt="Prometheus"/><br /><b>Prometheus</b></a></td>
|
||||
<td align="center"><a href="#big-data"><img src="images/big-data.png" width="75px;" height="75px;" alt="Big Data"/><br /><b>Big Data</b></a></td>
|
||||
<td align="center"><a href="topics/soft_skills/README.md"><img src="images/HR.png" width="75px;" height="75px;" alt="HR"/><br /><b>Soft Skills</b></a></td>
|
||||
<td align="center"><a href="topics/security/README.md"><img src="images/security.png" width="75px;" height="75px;" alt="security"/><br /><b>Security</b></a></td>
|
||||
<td align="center"><a href="topics/soft_skills"><img src="images/HR.png" width="75px;" height="75px;" alt="HR"/><br /><b>Soft Skills</b></a></td>
|
||||
<td align="center"><a href="topics/security"><img src="images/security.png" width="75px;" height="75px;" alt="security"/><br /><b>Security</b></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="topics/chaos_engineering/README.md"><img src="images/logos/chaos_engineering.png" width="75px;" height="75px;" alt="Chaos Engineering"/><br /><b>Chaos Engineering</b></a></td>
|
||||
<td align="center"><a href="topics/chaos_engineering"><img src="images/logos/chaos_engineering.png" width="75px;" height="75px;" alt="Chaos Engineering"/><br /><b>Chaos Engineering</b></a></td>
|
||||
<td align="center"><a href="#Misc"><img src="images/general.png" width="75px;" height="75px;" alt="Misc"/><br /><b>Misc</b></a></td>
|
||||
</tr>
|
||||
|
||||
|
@ -13,3 +13,13 @@
|
||||
* Private - Cloud services having computing resources limited to specific customer or organization, managed by third party or organizations itself
|
||||
* Hybrid - Combination of public and private clouds
|
||||
</b></details>
|
||||
|
||||
|
||||
<details>
|
||||
<summary>What is Azure Firewall?</summary><br><b>
|
||||
|
||||
Azure Firewall is a cloud-native and intelligent network firewall security service that provides the best of breed threat protection for your cloud workloads running in Azure.
|
||||
</b></details>
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import random
|
||||
import optparse
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
@ -39,9 +40,13 @@ def main():
|
||||
|
||||
if options.skip and not answer.strip():
|
||||
continue
|
||||
|
||||
if input(f'Q: {question} ...Show answer? "y" for yes: ').lower() == 'y':
|
||||
print('A: ', answer)
|
||||
os.system("clear")
|
||||
print(question)
|
||||
print("...Press Enter to show answer...")
|
||||
input()
|
||||
print('A: ', answer)
|
||||
print("... Press Enter to continue, Ctrl-C to exit")
|
||||
input()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
|
@ -1,5 +1,7 @@
|
||||
## Ansible
|
||||
|
||||
<!-- {% raw %} -->
|
||||
|
||||
### Ansible Exercises
|
||||
|
||||
|Name|Topic|Objective & Instructions|Solution|Comments|
|
||||
@ -527,3 +529,4 @@ If your group has 8 hosts. It will run the whole play on 4 hosts and then the sa
|
||||
<summary>What are collections in Ansible?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<!-- {% endraw %} -->
|
@ -1,5 +1,7 @@
|
||||
# Argo
|
||||
|
||||
<!-- {% raw %} -->
|
||||
|
||||
- [Argo](#argo)
|
||||
- [ArgoCD Exercises](#argocd-exercises)
|
||||
- [ArgoCD 101](#argocd-101)
|
||||
@ -503,4 +505,6 @@ It's an Analysis resource that fetches response status from Prometheus (monitori
|
||||
<summary>How do you monitor a rollout?</summary><br><b>
|
||||
|
||||
`kubectl argo rollouts get rollout SOME-APP --watch`
|
||||
</b></details>
|
||||
</b></details>
|
||||
|
||||
<!-- {% endraw %} -->
|
@ -1,5 +1,7 @@
|
||||
# Kubernetes
|
||||
|
||||
<!-- {% raw %} -->
|
||||
|
||||
What's your goal?
|
||||
|
||||
* I would like to prepare for CKA certification
|
||||
@ -3149,4 +3151,6 @@ Yes, using taints, we could run the following command and it will prevent from a
|
||||
<summary>You would like to limit the number of resources being used in your cluster. For example no more than 4 replicasets, 2 services, etc. How would you achieve that?</summary><br><b>
|
||||
|
||||
Using ResourceQuats
|
||||
</b></details>
|
||||
</b></details>
|
||||
|
||||
<!-- {% endraw %} -->
|
41
topics/python/solutions/compress_string_solution.md
Normal file
41
topics/python/solutions/compress_string_solution.md
Normal file
@ -0,0 +1,41 @@
|
||||
## Compress String Solution
|
||||
|
||||
1. Write a function that gets a string and compresses it
|
||||
- 'aaaabbccc' -> 'a4b2c3'
|
||||
- 'abbbc' -> 'a1b3c1'
|
||||
|
||||
```
|
||||
def compress_str(mystr: str) -> str:
|
||||
|
||||
result = ''
|
||||
|
||||
if mystr:
|
||||
prevchar = mystr[0]
|
||||
else:
|
||||
return result
|
||||
|
||||
count = 1
|
||||
for nextchar in mystr[1:]:
|
||||
if nextchar == prevchar:
|
||||
count += 1
|
||||
else:
|
||||
result += prevchar + str(count)
|
||||
count = 1
|
||||
prevchar = nextchar
|
||||
|
||||
result += prevchar + str(count)
|
||||
return result
|
||||
```
|
||||
|
||||
|
||||
2. Write a function that decompresses a given string
|
||||
- 'a4b2c3' -> 'aaaabbccc'
|
||||
- 'a1b3c1' -> 'abbbc'
|
||||
|
||||
```
|
||||
def decompress_str(mystr: str) -> str:
|
||||
result = ''
|
||||
for index in range(0, len(mystr), 2):
|
||||
result += mystr[index] * int(mystr[index + 1])
|
||||
return result
|
||||
```
|
@ -20,6 +20,8 @@ A couple of quotations from chosen companies:
|
||||
|
||||
<details>
|
||||
<summary>Explain the principle of least privilege</summary><br><b>
|
||||
|
||||
The principle of least privilege refers to the practice of providing minimal permissions to users, roles, and service accounts that allow them to perform their functions. If an entity does not require an access right then it should not have that right.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -71,6 +73,25 @@ Authorization is the process of identifying what level of access the service or
|
||||
A user uses the browser to authenticate to some server. It does so by using the authorization field which is constructed from the username and the password combined with a single colon. The result string is encoded using a certain character set which is compatible with US-ASCII. The authorization method + a space is prepended to the encoded string.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What are the three primary factors of authentication? Give three examples of each</summary><br><b>
|
||||
|
||||
Something you have
|
||||
- Smart card
|
||||
- Physical authentication device
|
||||
- Software token
|
||||
|
||||
Something you know
|
||||
- Password
|
||||
- PIN
|
||||
- Passphrase
|
||||
|
||||
Something you are
|
||||
- Fingerprint
|
||||
- Iris or retina scan
|
||||
- Gait analysis
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain Token-based authentication</summary><br><b>
|
||||
</b></details>
|
||||
@ -85,6 +106,18 @@ A user uses the browser to authenticate to some server. It does so by using the
|
||||
SSO (Single Sign-on), is a method of access control that enables a user to log in once and gain access to the resources of multiple software systems without being prompted to log in again.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain how the Kerberos authentication protocol works as a SSO solution</summary><br><b>
|
||||
|
||||
Kerberos works as a SSO solution by only requiring the user to sign in using their credentials once within a specific validity time window. Kerberos authentication grants the user a Ticket Granting Ticket (TGT) from a trusted authentication server which can then be used to request service tickets for accessing various services and resources. By passing around this encrypted TGT instead of credentials, the user does not need to sign-in multiple times for each resource that has been integrated with Kerberos.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Does Kerberos make use of symmetric encryption, asymmetric encryption, both, or neither?</summary><br><b>
|
||||
|
||||
Symmetric Encryption - Kerberos uses exclusively symmetric encryption with pre-shared keys for transmitting encrypted information and authorizing users.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain MFA (Multi-Factor Authentication)</summary><br><b>
|
||||
|
||||
@ -93,6 +126,10 @@ Multi-Factor Authentication (Also known as 2FA). Allows the user to present two
|
||||
- The credentials fall into any of these three categories: something you know (like a password or PIN), something you have (like a smart card), or something you are (like your fingerprint). Credentials must come from two different categories to enhance security.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain OAuth</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
#### Security - Passwords
|
||||
|
||||
<details>
|
||||
@ -124,6 +161,14 @@ Multi-Factor Authentication (Also known as 2FA). Allows the user to present two
|
||||
* MFA
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What is password salting? What attack does it help to deter?</summary><br><b>
|
||||
|
||||
Password salting is the processing of prepending or appending a series of characters to a user's password before hashing this new combined value. This value should be different for every single user but the same salt should be applied to the same user password everytime it is validated.
|
||||
|
||||
This ensures that users that have the same password will still have very different hash values stored in the password database. This process specifically helps deter rainbow table attacks since a new rainbow table would need to be computed for every single user in the database.
|
||||
</b></details>
|
||||
|
||||
#### Security - Cookies
|
||||
|
||||
<details>
|
||||
@ -204,6 +249,13 @@ True. It is only used during the key exchange algorithm of symmetric encryption.
|
||||
|
||||
<details>
|
||||
<summary>What is Hashing?</summary><br><b>
|
||||
|
||||
Hashing is a mathematical function for mapping data of arbitrary sizes to fixed-size values. This function produces a "digest" of the data that can be used for verifying that the data has not been modified (amongst other uses)
|
||||
</b></details>
|
||||
|
||||
<summary>How is hashing different from encryption?</summary><br><b>
|
||||
|
||||
Encrypted data can be decrypted to its original value. Hashed data cannot be reversed to view the original data - hashing is a one-way function.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -212,6 +264,7 @@ True. It is only used during the key exchange algorithm of symmetric encryption.
|
||||
Hashes used in SSH to verify the authenticity of messages and to verify that nothing tampered with the data received.
|
||||
</b></details>
|
||||
|
||||
#### Security - Attacks, Threats, and Vulnerabilities
|
||||
<details>
|
||||
<summary>Explain the following:
|
||||
|
||||
@ -257,6 +310,7 @@ You can test by using a stored procedure, so the application must be sanitize th
|
||||
|
||||
<details>
|
||||
<summary>How HTTPS is different from HTTP?</summary><br><b>
|
||||
The 'S' in HTTPS stands for 'secure'. HTTPS uses TLS to provide encryption of HTTP requests and responses, as well as providing verifaction by digitally signing requests and responses. As a result, HTTPS is far more secure than HTTP and is used by default for most modern websites.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -324,10 +378,6 @@ Stuxnet is a computer worm that was originally aimed at Iran’s nuclear facilit
|
||||
Spectre is an attack method which allows a hacker to “read over the shoulder” of a program it does not have access to. Using code, the hacker forces the program to pull up its encryption key allowing full access to the program
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain OAuth</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain "Format String Vulnerability"</summary><br><b>
|
||||
</b></details>
|
||||
@ -405,6 +455,10 @@ MAC address flooding attack (CAM table flooding attack) is a type of network att
|
||||
|
||||
<details>
|
||||
<summary>What is "Diffie-Hellman key exchange" and how does it work?</summary><br><b>
|
||||
|
||||
Have you heard of [The Two General's Problem](https://en.wikipedia.org/wiki/Two_Generals%27_Problem)? The Diffie-Hellman key exchange is a solution to this problem to allow for the secure exchange of cryptographic keys over an encrypted channel.
|
||||
|
||||
It works using public/private key pairs (asymmetric encryption). Two parties that wish to communicate securely over a public channel will each generate a public/private key pair and distribute the public key to the other party (note that public keys are free to be exchanged over a public channel). From here, each party can derive a shared key using a combination of their personal private key and the public key of the other party. This combined key can now be used as a symmetric encryption key for communications.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
|
@ -25,6 +25,7 @@
|
||||
- [Lists](#lists)
|
||||
- [Loops](#loops)
|
||||
- [Maps](#maps)
|
||||
- [Conditionals](#conditionals)
|
||||
- [Misc](#misc)
|
||||
- [Modules](#modules)
|
||||
- [Modules Hands-On](#modules-hands-on)
|
||||
@ -32,6 +33,7 @@
|
||||
- [Version Control](#version-control)
|
||||
- [AWS](#aws-1)
|
||||
- [Validations](#validations)
|
||||
- [Secrets](#secrets)
|
||||
- [Production](#production)
|
||||
|
||||
## Exercises
|
||||
@ -84,7 +86,7 @@
|
||||
<details>
|
||||
<summary>What language does Terraform uses?</summary><br><b>
|
||||
|
||||
A DSL called "HCL" (Hashiciorp Configuration Language). A declarative language for defining infrastructure.
|
||||
A DSL called "HCL" (Hashicorp Configuration Language). A declarative language for defining infrastructure.
|
||||
|
||||
</b></details>
|
||||
|
||||
@ -176,6 +178,14 @@ Run `terraform apply`. That will apply the changes described in your .tf files.
|
||||
* '-/+' - the resource or attribute is going to be replaced
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to cleanup Terraform resources? Why the user shold be careful doing so?</summary><br><b>
|
||||
|
||||
`terraform destroy` will cleanup all the resources tracked by Terraform.
|
||||
|
||||
A user should be careful with this command because there is no way to revert it. Sure, you can always run again "apply" but that can take time, generates completely new resources, etc.
|
||||
</b></details>
|
||||
|
||||
### Dependencies
|
||||
|
||||
<details>
|
||||
@ -251,6 +261,19 @@ terraform {
|
||||
azurerm and aws
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to install a provider? </summary><br><b>
|
||||
|
||||
You write a provider block like the following one and run `terraform init`
|
||||
|
||||
```
|
||||
provider "aws" {
|
||||
region = "us-west-1"
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>True or False? Applying the following Terraform configuration will fail since no source or version specific for 'aws' provider
|
||||
|
||||
@ -307,11 +330,28 @@ The Terraform Registry provides a centralized location for official and communit
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to cleanup Terraform resourcse? Why the user shold be careful doing so?</summary><br><b>
|
||||
<summary>Describe in high level what happens behind the scenes when you run terraform init on on the following Terraform configuration
|
||||
|
||||
`terraform destroy` will cleanup all the resources tracked by Terraform.
|
||||
```
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</summary><br><b>
|
||||
|
||||
A user should be careful with this command because there is no way to revert it. Sure, you can always run again "apply" but that can take time, generates completely new resources, etc.
|
||||
1. Terraform checks if there is an aws provider in this address: `registry.terraform.io/hashicorp/aws`
|
||||
2. Installs latest version of aws provider (assuming the URL exists and valid)
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>True or False? You can install providers only from hashicorp</summary><br><b>
|
||||
|
||||
False. You can specify any provider from any URL, not only those from hashicorp.
|
||||
</b></details>
|
||||
|
||||
### Variables
|
||||
@ -1143,7 +1183,7 @@ dynamic "tag" {
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You have a list variable called "users". You would like to define an output variable with a value of all users in uppercase. How to achieve that?</summary><br><b>
|
||||
<summary>There is a list variable called "users". You would like to define an output variable with a value of all users in uppercase. How to achieve that?</summary><br><b>
|
||||
|
||||
```
|
||||
output "users" {
|
||||
@ -1154,7 +1194,38 @@ output "users" {
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You have a list variable called "users". You would like to define an output variable with a value of all users in uppercase but only if the name is longer than 3 characters. How to achieve that?</summary><br><b>
|
||||
<summary>What's the result of the following code?
|
||||
|
||||
```
|
||||
resource "random_integer" "num" {
|
||||
min = 20
|
||||
max = 17
|
||||
}
|
||||
|
||||
resource "aws_instance" "instances" {
|
||||
count = random_integer.num.results
|
||||
}
|
||||
```
|
||||
|
||||
</summary><br><b>
|
||||
|
||||
The above code will fail as it's not possible to reference resource outputs with count, because Terraform has to compute count before any resources are created (or modified).
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>There is a variable called "values" with the following value: ["mario", "luigi", "peach"]. How to create an output variable with the string value of the items in the list: "mario, luigi, peach," ?</summary><br><b>
|
||||
|
||||
```
|
||||
output "users" {
|
||||
value = "%{ for name in var.values }${name}, %{ endfor }"
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>There is a list variable called "users". You would like to define an output variable with a value of all users in uppercase but only if the name is longer than 3 characters. How to achieve that?</summary><br><b>
|
||||
|
||||
```
|
||||
output "users" {
|
||||
@ -1189,11 +1260,91 @@ output "name_and_age" {
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You have a map variable, called "users", with the keys "name" (string) and "age" (float). Define an output map variable with the key being name in uppercase and value being age in the closest whole number </summary><br><b>
|
||||
|
||||
```
|
||||
output "name_and_age" {
|
||||
value = {for name, age in var.users : upper(name) => floor(age)
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
#### Conditionals
|
||||
|
||||
<details>
|
||||
<summary>How to use conditional expressions in Terraform?</summary><br><b>
|
||||
|
||||
`some_condition ? "value_if_true" : "value_if_false"`
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain the following condition: <code>var.x ? 1 : 0</code></summary><br><b>
|
||||
|
||||
If `x` evaluated to true, the result is 1, otherwise (if false) the result is 0.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain the following condition: <code>var.x != "" ? var.x : "yay"</code></summary><br><b>
|
||||
|
||||
If `x` is an empty string the result is "yay", otherwise it's the value of `x` variable
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Can conditionals be used with meta-arguments?</code></summary><br><b>
|
||||
|
||||
Yes, for example the "count" meta-argument:
|
||||
|
||||
```
|
||||
resource "aws_instance" "server" {
|
||||
count = var.amount ? 1 : 0
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Is it possible to combine conditionals and loop?</code></summary><br><b>
|
||||
|
||||
Yes, for example:
|
||||
|
||||
```
|
||||
dynamic "tag" {
|
||||
for_each = {
|
||||
for key, value in var.tags:
|
||||
key => value
|
||||
if key != ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
#### Misc
|
||||
|
||||
<details>
|
||||
<summary>Demonstrate using the ternary syntax</summary><br><b>
|
||||
<summary>What are meta-arguments in Terraform?</summary><br><b>
|
||||
|
||||
Arguments that affect the lifecycle of a resources (its creation, modification, ...) and supported by Terraform regardless to the type of resource in which they are used.
|
||||
|
||||
Some examples:
|
||||
|
||||
* count: how many resources to create out of one definition of a resource
|
||||
* lifecycle: how to treat resource creation or removal
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What meta-arguments are you familiar with?</summary><br><b>
|
||||
|
||||
* count: how many resources to create out of one definition of a resource
|
||||
* lifecycle: how to treat resource creation or removal
|
||||
* depends_on: create a dependency between resources
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -1234,14 +1385,9 @@ False. terraform console is ready-only.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What are meta-arguments in Terraform?</summary><br><b>
|
||||
<summary>Explain what <code>depends_on</code> used for and given an example</summary><br><b>
|
||||
|
||||
Arguments that affect the lifecycle of a resources (its creation, modification, ...) and supported by Terraform regardless to the type of resource in which they are used.
|
||||
|
||||
Some examples:
|
||||
|
||||
* count: how many resources to create out of one definition of a resource
|
||||
* lifecycle: how to treat resource creation or removal
|
||||
`depends_on` used to create a dependency between resources in Terraform. For example, there is an application you would like to deploy in a cluster. If the cluster isn't ready (and also managed by Terraform of course) then you can't deploy the app. In this case, you will define "depends_on" in the app configuration and its value will be the cluster resource.
|
||||
|
||||
</b></details>
|
||||
|
||||
@ -1362,29 +1508,8 @@ script = templatesfile("${path.module}/user-data.sh", {
|
||||
})
|
||||
</b></details>
|
||||
|
||||
### Import
|
||||
|
||||
<details>
|
||||
<summary>Explain Terraform's import functionality</summary><br><b>
|
||||
|
||||
`terraform import` is a CLI command used for importing an existing infrastructure into Terraform's state.
|
||||
|
||||
It's does NOT create the definitions/configuration for creating such infrastructure
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>State two use cases where you would use <code>terraform import</code></summary><br><b>
|
||||
|
||||
1. You have existing resources in the cloud and they are not managed by Terraform (as in not included in the state)
|
||||
2. You lost your tfstate file and need to rebuild it
|
||||
|
||||
</b></details>
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>There is a module to create an compute instance. How would you use the module to create three separate instances?</summary><br><b>
|
||||
<summary>There is a module to create a compute instance. How would you use the module to create three separate instances?</summary><br><b>
|
||||
|
||||
starting with Terraform 0.13, the `count` meta-argument can be used with modules. So you could use something like this:
|
||||
|
||||
@ -1400,6 +1525,25 @@ You can also use it in outputs vars: `value = module.instances[*]`
|
||||
|
||||
</b></details>
|
||||
|
||||
### Import
|
||||
|
||||
<details>
|
||||
<summary>Explain Terraform's import functionality</summary><br><b>
|
||||
|
||||
`terraform import` is a CLI command used for importing an existing infrastructure into Terraform's state.
|
||||
|
||||
It's does NOT create the definitions/configuration for creating such infrastructure.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>State two use cases where you would use <code>terraform import</code></summary><br><b>
|
||||
|
||||
1. You have existing resources in one of the providers and they are not managed by Terraform (as in not included in the state)
|
||||
2. You lost your tfstate file and need to rebuild it
|
||||
|
||||
</b></details>
|
||||
|
||||
### Version Control
|
||||
|
||||
<details>
|
||||
@ -1453,6 +1597,76 @@ This will change the order of how Terraform works. First it will create the new
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to manage multiple regions in AWS provider configuration?</summary><br><b>
|
||||
|
||||
```
|
||||
provider "aws" {
|
||||
region = "us-west-1"
|
||||
alias = "west_region"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "us-east-1"
|
||||
alias = "east_region"
|
||||
}
|
||||
|
||||
data "aws_region" "west_region" {
|
||||
provider = aws.west_region
|
||||
}
|
||||
|
||||
data "aws_region" "east_region" {
|
||||
provider = aws.east_region
|
||||
}
|
||||
```
|
||||
|
||||
To use it:
|
||||
|
||||
```
|
||||
resource "aws_instance" "west_region_instance" {
|
||||
provider = aws.west_region
|
||||
instance_type = "t2.micro"
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Assuming you have multiple regions configured and you would like to use a module in one of them. How to achieve that?</summary><br><b>
|
||||
|
||||
```
|
||||
module "some_module" {
|
||||
source = "..."
|
||||
|
||||
providers = {
|
||||
aws = aws.some_region
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to manage multiple AWS accounts?</summary><br><b>
|
||||
|
||||
One way is to define multiple different provider blocks, each with its own "assume_role"
|
||||
|
||||
```
|
||||
provider "aws" {
|
||||
region = "us-west-1"
|
||||
alias = "some-region"
|
||||
|
||||
assume_role {
|
||||
role_arn = "arn:aws:iam::<SOME_ACCOUNT_ID>:role/<SOME_ROLE_NAME>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
### Validations
|
||||
|
||||
<details>
|
||||
@ -1474,6 +1688,94 @@ variable "some_var" {
|
||||
|
||||
</b></details>
|
||||
|
||||
### Secrets
|
||||
|
||||
<details>
|
||||
<summary>What's the issue with the following provider configuration?
|
||||
|
||||
```
|
||||
provider "aws" {
|
||||
region = "us-west-1"
|
||||
|
||||
access_key = "blipblopblap"
|
||||
secret_key = "bipbopbipbop"
|
||||
}
|
||||
```
|
||||
</summary><br><b>
|
||||
|
||||
It's not secure! you should never store credentials in plain text this way.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What can you do to NOT store provider credentials in Terraform configuration files in plain text?</summary><br><b>
|
||||
|
||||
1. Use environment variables
|
||||
2. Use password CLIs (like 1Password which is generic but there also specific provider options like aws-vault)
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What can you do to NOT store provider credentials in Terraform configuration files in plain text?</summary><br><b>
|
||||
|
||||
1. Use environment variables
|
||||
2. Use password CLIs (like 1Password which is generic but there also specific provider options like aws-vault)
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How can you manage secrets/credentials in CI/CD?</summary><br><b>
|
||||
|
||||
That very much depends on the CI/CD system/platform you are using.
|
||||
|
||||
- GitHub Actions: Use Open ID Connect (OIDC) to establish connection with your provider. You then can specify in your GitHub Actions workflow the following:
|
||||
|
||||
```
|
||||
- uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::someIamRole
|
||||
aws-region: ...
|
||||
```
|
||||
|
||||
|
||||
- Jenkins: If Jenkins runs on the provider, you can use the provider access entities (like roles, policies, ...) to grant the instance, on which Jenkins is running, access control
|
||||
- CircleCI: you can use `CircleCI Context` and then specify it in your CircleCI config file
|
||||
|
||||
```
|
||||
context:
|
||||
- some-context
|
||||
```
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What are the pros and cons of using environment variables for managing secrets in Terraform configurations?</summary><br><b>
|
||||
|
||||
Pros:
|
||||
* You avoid using secrets directly in configurations in plain text
|
||||
* free (no need to pay for secret management platforms/solutions)
|
||||
* Straightforward to use
|
||||
|
||||
Cons:
|
||||
* Configurations might not be usable without the environment variables which may make impact the user experience as the user has to know what environment variables he should pass for everything to work properly
|
||||
* Mostly managed outside of Terraform mechanisms which makes it hard to enforce, track, ... anything that is related to secrets when it depends on the user to pass environment variables
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>True or False? If you pass secrets with environment variables, they are not visible in your state file</summary><br><b>
|
||||
|
||||
False. State files include sensitive data as it is. Which means it's very important that wherever you store your state file, it's encrypted and accessible only to those who should be able to access it.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>True or False? If you pass secrets from a centralized secrets store (like Hashicorp Vault) they are not visible in plan files (terraform plan)</summary><br><b>
|
||||
|
||||
False. It doesn't matter where your secrets store (file, environment variables, centralized secrets store), they will be visible in both state file and plan output.
|
||||
|
||||
</b></details>
|
||||
|
||||
### Production
|
||||
|
||||
This section is about how Terraform is actually used in real-life scenarios and organizations.
|
||||
@ -1521,12 +1823,14 @@ variables.tf
|
||||
dependencies.tf
|
||||
|
||||
Each one of these files can be divided to smaller parts if needed (no reason to maintain VERY long files)
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>An engineer in your team complains about having to copy-paste quite a lot of code between different folders and files of Terraform. What would you do?</summary><br><b>
|
||||
|
||||
Suggest to use Terraform modules.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
@ -1535,28 +1839,47 @@ Suggest to use Terraform modules.
|
||||
There are multiple ways to deal with it:
|
||||
1. Write scripts that perform some commands recurisvely with different conditions
|
||||
2. Use tools like Terragrunt where you commands like "run-all" that can run in parallel on multiple different paths
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>One of the engineers in your team complains the inline shell scripts are quite big and maintaining them in Terraform files seems like a bad idea. What would you do?</summary><br><b>
|
||||
|
||||
A good solution for not including shell scripts inline (as in inside terraform configuration files) is to keep them in a separate file and then use the terraform `templatefile` function to render and get them as a string
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You noticed a lot of your Terraform code/configuration is duplicated, between repositories and also within the same repository between different directories. What one way you may adopt that will help handling with that?</summary><br><b>
|
||||
|
||||
Using Terraform modules can help greatly with duplicated code and so different environments for example (staging and production) can reuse the same code by using the same modules.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You noticed your Terraform code includes quite a lot of hardcoded values (like ports, subnets, ...) and they are duplicated in many locations. How'd you deal with it?</summary><br><b>
|
||||
|
||||
Using variables might not be a good solution because some things shouldn't be exposed and accidentally overridden. In such case you might want to use the concept of `locals`
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Every time there is a change in tags standards (for example your team decided to change one of the tags' name) you find yourself changing tags in multiple files and you find the process quite tedious. What can be done about it?</summary><br><b>
|
||||
|
||||
Instead of defining tags at resource level, consider using `default_tags` as part of the provider configuration.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You would like to change the name of a resource but afraid to cause downtime. What can be done?</summary><br><b>
|
||||
|
||||
If it's a matter of changing a resource name, you could make use of `terraform state mv <ORIGINAL_RESOURCE_NAME> <NEW_RESOURCE_NAME>`
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>You try to deploy a cluster and an app on that cluster, but the app resource was created before the cluster. How to manage such situation?</summary><br><b>
|
||||
|
||||
Use the meta-argument `depends_on` in the app resource definition. This way the app will depend on the cluster resource and order will be maintained in creation of the resources.
|
||||
|
||||
</b></details>
|
Loading…
Reference in New Issue
Block a user