DevOps Fundamentals

DevOps Fundamentals: Linux, Jenkins, Docker, Kubernetes, Ansible and Terraform

Note

This guide is written for beginners, but the examples and practices are suitable for real development, test, and production environments.

Warning

Commands that use sudo, rm -r, package removal, network changes, Kubernetes deletion, Docker pruning, or terraform destroy can cause data loss or downtime. Test them in a lab before using them on production systems.

How to use this guide

  1. Practise Linux commands in a disposable virtual machine or container.
  2. Type each command yourself instead of only reading it.
  3. Keep application code, infrastructure code, and configuration in Git.
  4. Use the interview questions to test your understanding.
  5. Use each chapter's cheat sheet for revision.

Table of contents

  1. #1. Linux basics
  2. #2. VI and Vim editors
  3. #3. Linux user management
  4. #4. Downloading files with curl and wget
  5. #5. Operating-system and package management
  6. #6. Linux services and systemd
  7. #7. Linux networking
  8. #8. DNS and name resolution
  9. #9. Java and Java build tools
  10. #10. Jenkins
  11. #11. Docker
  12. #12. Kubernetes
  13. #13. Ansible
  14. #14. Terraform
  15. #15. Suggested hands-on learning path

1. Linux basics

What is Linux?

Linux is an operating-system kernel used by distributions such as Ubuntu, Debian, Rocky Linux, AlmaLinux, Red Hat Enterprise Linux, Amazon Linux, and Fedora. Most cloud servers, containers, Kubernetes nodes, and DevOps tools run on Linux.

Why do DevOps engineers use Linux?

Linux is stable, automatable, secure when configured correctly, and widely supported by cloud and infrastructure tools. A DevOps engineer commonly uses Linux to manage files, users, services, processes, networking, deployments, logs, and automation.

Tip

Use man <command> or <command> --help before using an unfamiliar option.

echo

What is it?

Prints text or variable values to standard output.

Why do we use it?

Use it in shell scripts, debugging, pipelines, and to create short text files.

Syntax

echo [OPTION] [TEXT]

Command breakdown

echo is the command. -n avoids the ending newline. -e enables supported escape sequences in many shells. $NAME expands a variable.

Example

echo "Hello Linux"
name="Madhan"
echo "User: $name"
echo -n "No newline"

Expected output

The supplied text or expanded variable appears in the terminal.

Common use cases

Printing status messages, checking variables, generating simple configuration lines.

Interview question

What is the difference between echo "$var" and echo $var? Quoting preserves spaces and prevents unwanted word splitting.

Common mistakes

Using echo for complex or untrusted data; shell implementations can differ.

Best practices

Quote variables and prefer printf when exact formatting is important.

Summary

echo quickly prints text and variable values.

pwd

What is it?

Prints the absolute path of the current working directory.

Why do we use it?

It confirms where you are before creating, editing, or deleting files.

Syntax

pwd [OPTION]

Command breakdown

-P resolves symbolic links to the physical path; -L keeps the logical path.

Example

pwd
pwd -P

Expected output

Example: /home/madhan/projects.

Common use cases

Navigation checks and safety checks before destructive commands.

Interview question

What does pwd stand for? Print working directory.

Common mistakes

Running rm or deployment commands without checking the current directory.

Best practices

Run pwd before bulk file operations.

Summary

pwd shows your current location.

ls

What is it?

Lists files and directories.

Why do we use it?

It helps inspect directory contents, permissions, owners, sizes, and timestamps.

Syntax

ls [OPTIONS] [PATH]

Command breakdown

-l long format, -a hidden files, -h human-readable sizes, -t sort by time, -R recursive.

Example

ls
ls -la
ls -lh /var/log
ls -lat

Expected output

A table or list of directory entries.

Common use cases

Finding files, checking permissions, reviewing recent log files.

Interview question

Why does ls not show .env by default? Names beginning with . are hidden.

Common mistakes

Assuming ls output is safe to parse in scripts.

Best practices

Use find, shell globs, or structured tools for scripts; use ls -lah interactively.

Summary

ls displays directory contents.

cd

What is it?

Changes the shell working directory.

Why do we use it?

It lets you navigate the filesystem.

Syntax

cd [DIRECTORY]

Command breakdown

cd .. moves to the parent, cd - returns to the previous directory, cd or cd ~ goes home.

Example

cd /var/log
cd ..
cd -
cd ~

Expected output

Usually no output; the shell location changes.

Common use cases

Moving between projects, configuration directories, and logs.

Interview question

What is the difference between an absolute and relative path? Absolute starts from /; relative starts from the current directory.

Common mistakes

Using paths containing spaces without quoting.

Best practices

Use tab completion and quote paths such as cd "My Project".

Summary

cd changes the current directory.

mkdir

What is it?

Creates a directory.

Why do we use it?

Applications need directories for source code, logs, uploads, configuration, and backups.

Syntax

mkdir [OPTIONS] DIRECTORY...

Command breakdown

-p creates missing parent directories and does not fail if directories already exist. -m sets permissions.

Example

mkdir reports
mkdir -p projects/api/config
mkdir -m 750 private-data

Expected output

Normally no output when successful.

Common use cases

Creating project structures and deployment directories.

Interview question

What does mkdir -p do? It creates the complete parent path safely.

Common mistakes

Creating nested paths without -p, or using insecure permissions.

Best practices

Use meaningful names and deliberate permissions.

Summary

mkdir creates one or more directories.

mkdir -p

What is it?

Creates a directory tree, including any missing parents.

Why do we use it?

It makes setup scripts repeatable and prevents “No such file or directory” errors.

Syntax

mkdir -p PATH...

Command breakdown

-p means parents. Existing directories are accepted without an error.

Example

mkdir -p /srv/myapp/{config,data,logs}

Expected output

Creates /srv/myapp and the three child directories.

Common use cases

Bootstrap scripts, CI/CD workspaces, container bind-mount directories.

Interview question

Why is mkdir -p useful in automation? It is idempotent for existing directory paths.

Common mistakes

Assuming it sets secure permissions automatically.

Best practices

Set ownership and permissions separately after creation.

Summary

mkdir -p creates nested directory paths safely.

rm

What is it?

Removes files; with options it can remove directories.

Why do we use it?

It cleans temporary files, obsolete artifacts, and incorrect files.

Syntax

rm [OPTIONS] FILE...

Command breakdown

-i asks before removal, -f forces, -v shows removed files, -r recursively removes directories.

Example

rm old.txt
rm -i important.txt
rm -v *.tmp

Expected output

Normally no output unless verbose or an error occurs.

Common use cases

Cleanup scripts and removal of old build outputs.

Interview question

Can a normal rm be undone? Not reliably; it normally bypasses the desktop recycle bin.

Common mistakes

Using broad wildcards, running as root, or typing an incorrect absolute path.

Best practices

Preview with ls, use -i when learning, and keep backups.

Summary

rm permanently removes filesystem entries.

rm -r

What is it?

Recursively removes a directory and everything inside it.

Why do we use it?

It is used to delete directory trees such as generated build folders.

Syntax

rm -r DIRECTORY

Command breakdown

-r traverses child directories. -f suppresses prompts and many errors, making rm -rf especially dangerous.

Example

rm -r build/
rm -ri old-project/

Expected output

The directory tree is removed.

Common use cases

Removing generated dependencies, cache folders, or temporary environments.

Interview question

Why is rm -rf / dangerous? It attempts recursive forced deletion from the filesystem root.

Common mistakes

Copying destructive commands without checking variables or the current path.

Best practices

Use safeguards such as set -u, parameter validation, backups, and least privilege.

Summary

rm -r recursively deletes directories.

cp

What is it?

Copies files.

Why do we use it?

It creates backups, stages configuration, and duplicates templates.

Syntax

cp [OPTIONS] SOURCE DESTINATION

Command breakdown

-i prompts before overwrite, -v is verbose, -p preserves metadata, -a archives recursively and preserves attributes.

Example

cp app.conf app.conf.bak
cp -iv source.txt /tmp/
cp -p script.sh backup/

Expected output

The destination file is created or replaced.

Common use cases

Backups, deployment staging, copying configuration templates.

Interview question

What is the difference between cp -r and cp -a? -a preserves more metadata and links.

Common mistakes

Overwriting a destination unintentionally.

Best practices

Use -i interactively and version configuration in Git.

Summary

cp copies files.

cp -r

What is it?

Recursively copies directories.

Why do we use it?

It duplicates a complete project or directory tree.

Syntax

cp -r SOURCE_DIRECTORY DESTINATION

Command breakdown

-r copies each child recursively.

Example

cp -r website/ website-backup/

Expected output

A new directory tree is created at the destination.

Common use cases

Local backups and copying static assets.

Interview question

What happens if the destination directory exists? The source may be copied inside it depending on paths.

Common mistakes

Unexpected nested directories and missing metadata preservation.

Best practices

Use trailing paths carefully; prefer cp -a for backups.

Summary

cp -r copies directory trees.

mv

What is it?

Moves or renames files and directories.

Why do we use it?

It reorganizes files and performs atomic renames on the same filesystem.

Syntax

mv [OPTIONS] SOURCE DESTINATION

Command breakdown

-i prompts before overwrite, -n never overwrites, -v shows actions.

Example

mv draft.txt final.txt
mv -i app.conf /etc/myapp/
mv logs/ archive/

Expected output

The source path disappears and the destination path exists.

Common use cases

Renaming releases, organizing files, deploying with directory swaps.

Interview question

Is mv always atomic? Renames on the same filesystem commonly are; cross-filesystem moves require copy and delete.

Common mistakes

Overwriting existing files or moving into the wrong directory.

Best practices

Use -i or -n, and verify destination ownership.

Summary

mv moves or renames files and directories.

touch

What is it?

Creates an empty file if absent or updates timestamps if present.

Why do we use it?

It quickly creates placeholders and can trigger timestamp-based workflows.

Syntax

touch [OPTIONS] FILE...

Command breakdown

-c does not create missing files; -t supplies a timestamp.

Example

touch new.txt
touch .env.example
touch -c existing.txt

Expected output

A zero-byte file may be created; otherwise timestamps change.

Common use cases

Creating files before editing and updating modification times.

Interview question

Does touch clear an existing file? No.

Common mistakes

Expecting it to write content.

Best practices

Use meaningful extensions and correct ownership.

Summary

touch creates empty files or updates timestamps.

cat

What is it?

Reads and concatenates files to standard output.

Why do we use it?

It is useful for short files, pipelines, and joining content.

Syntax

cat [OPTIONS] [FILE...]

Command breakdown

-n numbers lines; multiple files are printed in order.

Example

cat /etc/os-release
cat -n app.conf
cat part1 part2 > combined.txt

Expected output

File contents appear in the terminal or are redirected.

Common use cases

Viewing short configuration files and combining files.

Interview question

Why is cat not ideal for huge logs? It prints everything at once.

Common mistakes

Using it on binary or very large files.

Best practices

Use less for long files and tail for live logs.

Summary

cat prints or combines file contents.

cat > file

What is it?

Redirects standard input into a file and overwrites it.

Why do we use it?

It quickly creates a small file from terminal input or command output.

Syntax

cat > FILE
# type content
# press Ctrl+D to finish

Command breakdown

> redirects and truncates the destination before writing. Ctrl+D sends end-of-file from an interactive terminal.

Example

cat > new.txt
Hello Linux
This file is new.
# Press Ctrl+D

Expected output

new.txt contains the typed lines; old contents are lost.

Common use cases

Creating short lab files and test configuration.

Interview question

What is the difference between > and >>? > overwrites; >> appends.

Common mistakes

Accidentally truncating a valuable file.

Best practices

Use an editor or a here-document for important multi-line configuration.

Summary

cat > creates or replaces a file with input.

cat >> file

What is it?

Appends standard input to the end of a file.

Why do we use it?

It adds lines without deleting existing content.

Syntax

cat >> FILE
# type content
# press Ctrl+D

Command breakdown

>> opens the destination in append mode.

Example

cat >> notes.txt
Additional note
# Press Ctrl+D

Expected output

The new lines appear after the old content.

Common use cases

Appending host entries or notes in controlled scripts.

Interview question

Can repeated automation create duplicates with >>? Yes.

Common mistakes

Appending duplicate or malformed configuration repeatedly.

Best practices

Check before appending; use configuration-management tools for production.

Summary

cat >> appends input to a file.

less

What is it?

Views text one screen at a time without loading everything into the terminal.

Why do we use it?

It is ideal for logs, manuals, and long configuration files.

Syntax

less [OPTIONS] FILE

Command breakdown

Use /text to search, n next result, N previous, g top, G bottom, q quit, -S prevents line wrapping.

Example

less /var/log/syslog
less -S access.log

Expected output

An interactive pager opens.

Common use cases

Reading long logs and command output.

Interview question

How do you follow a growing file in less? Press F; use Ctrl+C to stop following.

Common mistakes

Using cat where interactive navigation is needed.

Best practices

Pipe output to less, for example systemctl status app | less.

Summary

less is an interactive file viewer.

head

What is it?

Prints the beginning of a file.

Why do we use it?

It quickly checks headers, sample rows, and initial log lines.

Syntax

head [OPTIONS] FILE

Command breakdown

-n N prints N lines; -c N prints N bytes.

Example

head app.log
head -n 20 data.csv

Expected output

By default, the first 10 lines.

Common use cases

Inspecting CSV headers and initial configuration.

Interview question

How do you show the first five lines? head -n 5 file.

Common mistakes

Assuming it validates the entire file.

Best practices

Use it for inspection, not completeness checks.

Summary

head prints the start of a file.

tail

What is it?

Prints the end of a file and can follow changes.

Why do we use it?

It is one of the main tools for monitoring application logs.

Syntax

tail [OPTIONS] FILE

Command breakdown

-n N prints N lines; -f follows; -F follows by name and handles rotation better.

Example

tail -n 50 app.log
tail -F /var/log/nginx/access.log

Expected output

The last lines appear; follow mode continues printing new lines.

Common use cases

Live troubleshooting and watching deployment logs.

Interview question

Difference between -f and -F? -F retries and follows a filename across rotation.

Common mistakes

Leaving follow sessions running or watching the wrong environment.

Best practices

Use timestamps and structured logging; stop with Ctrl+C.

Summary

tail reads the end of files and follows logs.

grep

What is it?

Searches text for lines matching a pattern.

Why do we use it?

It filters logs, configuration, process output, and command results.

Syntax

grep [OPTIONS] PATTERN [FILE...]

Command breakdown

-i ignore case, -n line number, -r recursive, -v invert, -E extended regex, -w whole word.

Example

grep -n "ERROR" app.log
grep -ri "database" config/
ps aux | grep nginx

Expected output

Matching lines are printed.

Common use cases

Log analysis, configuration searches, and pipeline filtering.

Interview question

What does exit status 1 mean? No matching line; it is not necessarily a command failure.

Common mistakes

Forgetting to quote regex patterns or matching the grep process itself.

Best practices

Use grep -F for literal text and grep -R carefully on large trees.

Summary

grep finds matching text.

find

What is it?

Searches the filesystem using names, types, sizes, ownership, times, and other conditions.

Why do we use it?

It finds files reliably and can execute actions on matches.

Syntax

find PATH [TESTS] [ACTIONS]

Command breakdown

-name, -iname, -type f|d, -size, -mtime, -user, -exec ... {} \;.

Example

find . -type f -name "*.log"
find /var/log -type f -mtime +30
find . -type f -name "*.tmp" -delete

Expected output

Matching paths are printed unless another action is used.

Common use cases

Cleanup, locating configuration, and audit checks.

Interview question

Why quote "*.log"? It prevents the shell from expanding it before find runs.

Common mistakes

Using -delete or -exec rm before reviewing matches.

Best practices

Run the same find without deletion first.

Summary

find locates files using detailed conditions.

chmod

What is it?

Changes file permission bits.

Why do we use it?

It controls who can read, write, or execute files.

Syntax

chmod [OPTIONS] MODE FILE...

Command breakdown

Symbolic: u/g/o/a plus +/-/= and r/w/x. Numeric: read=4, write=2, execute=1; e.g. 750.

Example

chmod +x deploy.sh
chmod 640 app.conf
chmod -R u=rwX,g=rX,o= webroot/

Expected output

Permissions change; normally no output.

Common use cases

Making scripts executable and protecting secrets.

Interview question

What does 755 mean? Owner rwx, group r-x, others r-x.

Common mistakes

Using chmod 777 as a quick fix or adding execute permission to data files.

Best practices

Apply least privilege and understand directory execute permission.

Summary

chmod changes file and directory permissions.

chown

What is it?

Changes file owner and optionally group.

Why do we use it?

Services need correct ownership to read configuration and write data safely.

Syntax

chown [OPTIONS] OWNER[:GROUP] FILE...

Command breakdown

-R recursive; user:group changes both owner and group.

Example

sudo chown appuser:appgroup app.conf
sudo chown -R appuser:appgroup /srv/myapp/data

Expected output

Ownership changes.

Common use cases

Fixing deployment ownership and service data directories.

Interview question

Why can normal users not give files to arbitrary users? It would bypass quotas and security controls.

Common mistakes

Recursively changing ownership on system paths or mounted data without review.

Best practices

Limit the target path and verify with ls -l.

Summary

chown changes ownership.

ln

What is it?

Creates hard links or symbolic links.

Why do we use it?

Links provide aliases, versioned release pointers, and shared file references.

Syntax

ln [OPTIONS] TARGET LINK_NAME

Command breakdown

Without -s, creates a hard link. -s creates a symbolic link. -f replaces destination; -n affects symlink handling.

Example

ln -s /srv/releases/2026-07-24 /srv/current
ln original.txt second-name.txt

Expected output

A new link path is created.

Common use cases

Pointing current to a release and managing shared configuration.

Interview question

Difference between hard and symbolic links? Hard links reference the same inode; symbolic links store a path.

Common mistakes

Creating relative symlinks from the wrong directory or deleting a target and leaving a broken link.

Best practices

Use absolute targets for operational links unless portability requires relative links.

Summary

ln creates hard or symbolic links.

history

What is it?

Displays shell command history.

Why do we use it?

It helps repeat commands and review recent work.

Syntax

history [N]

Command breakdown

history 20 shows the latest 20 entries. !! repeats the last command; !123 repeats entry 123, but verify before use.

Example

history 20
history | grep kubectl

Expected output

Numbered previous commands appear.

Common use cases

Troubleshooting and recalling long commands.

Interview question

Where is Bash history usually stored? ~/.bash_history, with session behavior controlled by shell settings.

Common mistakes

Leaving passwords or tokens in command-line history.

Best practices

Use secret managers, environment injection, and history-safe methods.

Summary

history shows prior shell commands.

clear

What is it?

Clears the visible terminal screen.

Why do we use it?

It reduces visual clutter while keeping the shell session active.

Syntax

clear

Command breakdown

No important arguments for normal use; Ctrl+L often provides similar behavior.

Example

clear

Expected output

The terminal viewport is cleared.

Common use cases

Improving readability during demonstrations.

Interview question

Does clear delete command history? No.

Common mistakes

Assuming it removes sensitive data from scrollback or logs.

Best practices

Close or reset the terminal when sensitive scrollback must be removed.

Summary

clear cleans the terminal display, not history.

Linux basics: interview questions

  1. What is the difference between an absolute path and a relative path?
  2. What is the difference between > and >>?
  3. Explain Linux permissions such as 640, 750, and 755.
  4. What is the difference between a hard link and a symbolic link?
  5. How would you locate files older than 30 days?
  6. Why is rm -rf dangerous in automation?
  7. How do you follow a log file across log rotation?

Linux basics cheat sheet

Goal Command
Show location pwd
List all files ls -lah
Create nested folders mkdir -p a/b/c
Copy a directory safely cp -a source/ backup/
Rename a file mv old new
View a long file less file
Follow a log tail -F app.log
Search text grep -Rni "text" path/
Find log files find . -type f -name "*.log"
Make script executable chmod +x script.sh
Change ownership sudo chown user:group file

2. VI and Vim editors

What are VI and Vim?

vi is a modal terminal text editor available on many Unix-like systems. Vim means Vi Improved and provides more features, syntax highlighting, plugins, and improved editing behavior.

Why do we use them?

Servers may not have a graphical editor. VI or Vim lets an administrator edit configuration, scripts, Kubernetes YAML, service files, and emergency fixes through an SSH terminal.

Editor modes

Mode Enter mode Purpose
Normal/command Press Esc Navigate and run editing commands
Insert Press i, a, o, etc. Type text
Visual Press v, V, or Ctrl+V Select characters, lines, or blocks
Command-line Press : in normal mode Save, quit, replace, configure
vim app.conf

Essential commands

Action Command Explanation
Insert before cursor i Enters insert mode
Append after cursor a Enters insert mode after cursor
New line below o Opens a line below
Return to normal mode Esc Stops inserting/selecting
Delete character x Deletes character under cursor
Delete line dd Deletes/cuts the current line
Delete 5 lines 5dd Repeats dd five times
Copy line yy Yanks the current line
Copy 5 lines 5yy Yanks five lines
Paste after p Pastes after cursor/current line
Paste before P Pastes before cursor/current line
Undo u Undoes last change
Redo Ctrl+r Redoes an undone change
Search forward /word Searches for word
Next occurrence n Repeats search in same direction
Previous occurrence N Repeats search in reverse
Replace current line :s/old/new/g Replaces every match in current line
Replace whole file :%s/old/new/g Replaces every match in the file
Confirm each replacement :%s/old/new/gc Prompts before each change
Save :w Writes the file
Quit :q Quits if no unsaved change
Save and quit :wq or ZZ Saves and closes
Quit without saving :q! Discards unsaved changes
Go to first line gg Moves to top
Go to last line G Moves to bottom
Page down Ctrl+f Scrolls one page forward
Page up Ctrl+b Scrolls one page backward
Half-page down Ctrl+d Scrolls half a page down
Half-page up Ctrl+u Scrolls half a page up
Note

Ctrl+p is commonly completion or movement to the previous line depending on mode; it is not the normal page-up command. Use Ctrl+b for page up and Ctrl+f for page down.

Practical example

sudo vim /etc/hosts
  1. Press i.
  2. Add the required entry.
  3. Press Esc.
  4. Type :wq and press Enter.

Common mistakes

Best practices

Interview questions

  1. Explain Vim's normal, insert, visual, and command-line modes.
  2. How do you copy five lines and paste them?
  3. How do you replace a word throughout a file with confirmation?
  4. What is the difference between :q, :q!, and :wq?

VI/Vim cheat sheet

Open: vim file
Insert: i
Normal mode: Esc
Delete line: dd
Copy line: yy
Paste: p
Undo: u
Redo: Ctrl+r
Search: /word
Next: n
Save: :w
Save and exit: :wq
Discard and exit: :q!

3. Linux user management

whoami

What is it?

Prints the effective username of the current process.

Why do we use it?

It confirms which account is executing commands.

Syntax

whoami

Command breakdown

There are no commonly required options.

Example

whoami

Expected output

Example: madhan or root.

Common use cases

Checking privilege context before administration.

Interview question

Difference between login user and effective user? sudo can change the effective identity for a command.

Common mistakes

Assuming the shell is running as the expected user.

Best practices

Check identity before destructive actions.

Summary

whoami prints the effective username.

id

What is it?

Displays user ID, group ID, and group memberships.

Why do we use it?

Permissions are evaluated using numeric IDs and groups.

Syntax

id [USER]

Command breakdown

Without a user, shows current identity. -u, -g, and -G show IDs.

Example

id
id appuser
id -u

Expected output

Example: uid=1000(madhan) gid=1000(madhan) groups=....

Common use cases

Debugging file access and service accounts.

Interview question

Why can a user gain access after joining a group only after a new login? Group membership is loaded into the session.

Common mistakes

Looking only at usernames and ignoring numeric IDs on mounted storage.

Best practices

Use dedicated service accounts and least-privilege groups.

Summary

id shows numeric and named identity information.

su

What is it?

Starts a shell as another user.

Why do we use it?

It is used for testing a service account or switching administrative context.

Syntax

su [OPTIONS] [USER]

Command breakdown

su - user starts a login shell with the target user environment. Without a username, it normally targets root.

Example

su - appuser
su -

Expected output

A new shell starts after authentication.

Common use cases

Testing permissions and running commands as a service user.

Interview question

Difference between su user and su - user? The hyphen loads the target login environment.

Common mistakes

Using a mixed environment without - or sharing root passwords.

Best practices

Prefer sudo with audited, limited permissions.

Summary

su switches user shells.

sudo

What is it?

Runs an allowed command with another identity, usually root.

Why do we use it?

It grants controlled administrative access and creates audit records.

Syntax

sudo [OPTIONS] COMMAND

Command breakdown

-u user chooses an account, -i starts a login shell, -l lists allowed commands.

Example

sudo systemctl restart nginx
sudo -u www-data id
sudo -l

Expected output

The command runs with elevated or alternate privileges.

Common use cases

Package installation, service control, and protected file changes.

Interview question

Where is sudo policy configured? Commonly /etc/sudoers and /etc/sudoers.d/, edited with visudo.

Common mistakes

Granting unrestricted NOPASSWD: ALL or running entire scripts as root unnecessarily.

Best practices

Grant the minimum command set and use visudo.

Summary

sudo provides controlled privilege escalation.

passwd

What is it?

Changes a user password and manages password status.

Why do we use it?

It secures interactive accounts and can lock or expire passwords.

Syntax

passwd [OPTIONS] [USER]

Command breakdown

Normal users change their own password; root can target another user. Common administrative options include -l lock and -u unlock, subject to distribution behavior.

Example

passwd
sudo passwd appuser
sudo passwd -l olduser

Expected output

Interactive password prompts or a status message.

Common use cases

Account onboarding, credential rotation, and disabling login.

Interview question

Does locking a password always disable every login method? No; SSH keys or other methods may still work.

Common mistakes

Using weak passwords or assuming a locked password disables all access.

Best practices

Prefer SSH keys, MFA where available, and remove unused accounts.

Summary

passwd manages account passwords.

groups

What is it?

Lists group memberships for a user.

Why do we use it?

Groups provide shared access without giving broad permissions.

Syntax

groups [USER]

Command breakdown

Without a user, displays groups for the current identity.

Example

groups
groups appuser

Expected output

A space-separated group list.

Common use cases

Debugging permissions and validating onboarding.

Interview question

How do supplementary groups affect permissions? Any matching group permission may grant access.

Common mistakes

Expecting a current shell to see newly added groups immediately.

Best practices

Start a new login session after group changes.

Summary

groups shows group membership.

User-management production example

sudo useradd --create-home --shell /bin/bash deploy
sudo passwd deploy
sudo usermod -aG docker deploy
id deploy
Warning

Membership in the docker group commonly provides root-equivalent control over the Docker host. Grant it only to trusted administrators.

Interview questions

  1. What is the difference between a UID and a GID?
  2. Why is sudo generally preferred to sharing the root password?
  3. What is the difference between su user and su - user?
  4. How do supplementary groups affect file permissions?

User-management cheat sheet

Goal Command
Current username whoami
Identity and groups id
Switch with login environment su - user
Run one privileged command sudo command
View sudo rights sudo -l
Change password passwd
Show groups groups user

4. Downloading files with curl and wget

curl

What is it?

Transfers data using URLs and supports HTTP, HTTPS, APIs, authentication, headers, uploads, and many other protocols.

Why do we use it?

DevOps engineers use it to test APIs, check health endpoints, download artifacts, and automate web requests.

Syntax

curl [OPTIONS] URL

Command breakdown

-o FILE saves to a chosen filename; -O uses the remote filename; -L follows redirects; -I fetches headers; -f fails on HTTP errors; -sS is quiet but still shows errors; -H adds a header; -X sets a method; -d sends data; --connect-timeout and --max-time limit waiting.

Example

curl https://example.com
curl -fL https://example.com/app.tar.gz -o app.tar.gz
curl -I https://example.com
curl -sS -H "Authorization: Bearer $TOKEN" https://api.example.com/health
curl -X POST -H "Content-Type: application/json" -d '{"name":"demo"}' https://api.example.com/items

Expected output

Response content is printed unless redirected; with -o, the file is saved. Exit status is non-zero for many failures, especially when -f is used.

Common use cases

API testing, health checks, artifact download, webhook testing.

Interview question

Why combine -f, -L, -s, and -S in scripts? Follow redirects, fail on HTTP errors, hide progress, and still show errors.

Common mistakes

Not following redirects, printing secrets, ignoring status codes, or downloading unverified files.

Best practices

Use TLS, checksums/signatures, timeouts, --retry, and secret-safe headers.

Summary

curl is a general-purpose URL and API client.

wget

What is it?

Downloads files non-interactively and supports recursive retrieval, resuming, and mirroring.

Why do we use it?

It is convenient for downloading packages or larger files from scripts and terminals.

Syntax

wget [OPTIONS] URL

Command breakdown

-O FILE chooses output filename; -c continues a partial download; -q is quiet; --show-progress displays progress; --timeout; --tries; --content-disposition respects server filenames.

Example

wget https://example.com/app.tar.gz
wget -O some-file.txt https://example.com/data
wget -c https://example.com/large.iso

Expected output

The file is written to the current directory or selected path, with progress information.

Common use cases

Downloading release artifacts and resuming large downloads.

Interview question

Difference between wget -O and curl -o? Both choose a local name; the option letters use different cases.

Common mistakes

Using -O with multiple URLs, disabling certificate checks, or trusting unverified downloads.

Best practices

Verify checksums and avoid --no-check-certificate in production.

Summary

wget is focused on reliable non-interactive downloads.

Download verification example

curl -fL https://example.com/app.tar.gz -o app.tar.gz
sha256sum app.tar.gz
# Compare the hash with a trusted value supplied by the publisher.

Interview questions

  1. How do you make curl fail when a server returns HTTP 404 or 500?
  2. How do you follow HTTP redirects?
  3. How do you resume a partial wget download?
  4. Why should downloaded binaries be verified?

Download cheat sheet

Goal curl wget
Save as filename curl -o file URL wget -O file URL
Keep remote name curl -O URL wget URL
Follow redirect curl -L URL Usually handled automatically
Fail on HTTP errors curl -f URL Non-zero status for server errors
Resume curl -C - -O URL wget -c URL

5. Operating-system and package management

Detecting the operating system

/etc/os-release

What is it?

A standard text file containing distribution identification such as name, version, and ID.

Why do we use it?

Automation needs to know whether it is running on Ubuntu, Debian, Rocky Linux, RHEL, or another distribution before choosing a package manager or service name.

Syntax and example

cat /etc/os-release
ls /etc/*release*
cat /etc/*release*

Expected output

NAME="Ubuntu"
VERSION="24.04 LTS ..."
ID=ubuntu
VERSION_ID="24.04"

Best practice

Prefer /etc/os-release in scripts. Globbing every release file is useful for manual investigation but produces distribution-specific content.

Package-management overview

Distribution family Low-level tool High-level tool
RHEL, Rocky, AlmaLinux, Fedora rpm dnf (yum may be a compatibility command)
Debian, Ubuntu dpkg apt / apt-get

rpm

What is it?

The low-level RPM Package Manager for installing, querying, verifying, and removing .rpm packages.

Syntax and examples

sudo rpm -i package.rpm
sudo rpm -Uvh package.rpm
sudo rpm -e package-name
rpm -q package-name
rpm -qa
rpm -ql package-name
rpm -qf /usr/bin/curl
rpm -V package-name

Command breakdown

Tip

Prefer dnf install ./package.rpm when possible because it resolves dependencies. Direct rpm -i does not automatically resolve all dependencies.

yum and dnf

What are they?

High-level package managers for RPM-based systems. Modern Fedora and current RHEL-family systems generally use DNF; yum may map to DNF for compatibility.

Examples

sudo dnf install ansible-core
sudo dnf remove ansible-core
dnf list installed ansible-core
dnf search nginx
sudo dnf update
sudo dnf clean all
sudo yum install httpd

Common options

apt

What is it?

A high-level package command used on Debian and Ubuntu systems.

Examples

sudo apt update
sudo apt install nginx
sudo apt remove nginx
sudo apt purge nginx
apt search ansible
apt show ansible
sudo apt upgrade
sudo apt autoremove

Important distinction

apt update refreshes repository metadata. It does not upgrade installed packages. apt upgrade installs available upgrades based on the refreshed metadata.

Common mistakes

Best practices

Interview questions

  1. What is the difference between RPM and DNF/YUM?
  2. What is the difference between apt update and apt upgrade?
  3. How do you find which RPM package owns a file?
  4. Why should repositories and packages be signature-verified?

Package-management cheat sheet

Goal RHEL family Debian/Ubuntu
Refresh metadata dnf makecache apt update
Install dnf install pkg apt install pkg
Remove dnf remove pkg apt remove pkg
Search dnf search text apt search text
Package info dnf info pkg apt show pkg
Upgrade dnf upgrade apt upgrade

6. Linux services and systemd

What is a service?

A service is a long-running background process such as Nginx, PostgreSQL, Docker, Jenkins, or SSH. Modern Linux distributions commonly manage services with systemd and the systemctl command.

service vs systemctl

Command Meaning
service nginx start Compatibility interface, often translated to the system's service manager
systemctl start nginx Native systemd service control

Use systemctl on systemd-based distributions.

Core service commands

sudo systemctl start httpd
sudo systemctl stop httpd
sudo systemctl restart httpd
sudo systemctl reload httpd
sudo systemctl enable httpd
sudo systemctl disable httpd
systemctl status httpd
systemctl is-active httpd
systemctl is-enabled httpd
journalctl -u httpd
journalctl -u httpd -f

Command meanings

Action What it does Downtime risk
start Starts a stopped service Low, assuming healthy configuration
stop Stops a running service High for dependent applications
restart Stops and starts again Usually causes a brief interruption
reload Asks service to reload configuration without full restart Lower, but service must support it
enable Configures startup during boot Does not necessarily start now
disable Removes automatic boot startup Does not necessarily stop now
status Shows state and recent logs Safe read-only operation
Note

systemctl enable --now nginx both enables the unit for boot and starts it immediately.

Unit file example

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/java -jar /srv/myapp/app.jar
Restart=on-failure
RestartSec=5
EnvironmentFile=-/etc/myapp/myapp.env
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -f

Common mistakes

Best practices

Interview questions

  1. What is the difference between start, restart, and reload?
  2. What is the difference between enable and start?
  3. Why is daemon-reload required?
  4. How do you view logs for a systemd service?

Services cheat sheet

systemctl status nginx
sudo systemctl start nginx
sudo systemctl reload nginx
sudo systemctl restart nginx
sudo systemctl enable --now nginx
sudo systemctl disable --now nginx
journalctl -u nginx -f

7. Linux networking

Networking concepts

IP address

An IP address identifies a network interface at the Internet Protocol layer. IPv4 example: 192.168.1.10. IPv6 example: 2001:db8::10.

Subnet and prefix

A subnet groups addresses that can communicate directly at Layer 3 without using a router. In 192.168.1.10/24, /24 means the first 24 bits identify the network. The typical address range is 192.168.1.0 through 192.168.1.255, though the first and last addresses have special roles in a traditional IPv4 subnet.

Default gateway

A default gateway is the router used when no more specific route matches the destination.

Router

A router forwards packets between networks. A Linux host can act as a router when forwarding is enabled and routing/firewall rules are configured.

DNS

DNS converts names such as db.internal.example into IP addresses and can store other records.

MAC address

A MAC address identifies a network interface at the local data-link layer, for example 52:54:00:12:34:56.

Interface

An interface is a network connection such as eth0, ens3, enp1s0, wlan0, or lo.

Static IP

A static address is configured to remain stable. Production servers often need predictable addresses, although clouds may attach stable private IP resources through their own control plane.

DHCP

Dynamic Host Configuration Protocol supplies network settings such as IP address, prefix, gateway, and DNS servers automatically.

Network diagram

                         Internet / Other Networks
                                  |
                            [ ISP / Router ]
                                  |
                         Default gateway: 192.168.1.1
                                  |
        ----------------------------------------------------
        |                    192.168.1.0/24                 |
        |                                                   |
 [App Server]             [DB Server]                [DNS Server]
 192.168.1.10             192.168.1.11               192.168.1.100
 MAC: aa:...              MAC: bb:...                MAC: cc:...
        |                                                   |
        -------------------- Local switch -------------------

What is it?

Shows and changes link-layer interface state.

Commands

ip link
ip -br link
sudo ip link set dev eth0 up
sudo ip link set dev eth0 down

Output

Shows interface name, flags, MTU, state, and MAC address.

ip addr

What is it?

Shows and changes IP addresses assigned to interfaces.

Commands

ip addr
ip -br addr
sudo ip addr add 192.168.1.10/24 dev eth0
sudo ip addr del 192.168.1.10/24 dev eth0

Command breakdown

Warning

Commands entered with ip addr add are generally runtime changes and may disappear after reboot. Use the distribution's persistent network configuration, NetworkManager, Netplan, systemd-networkd, or the cloud network configuration for permanent settings.

ip route

What is it?

Displays and manages the kernel routing table.

Commands

ip route
ip route get 8.8.8.8
sudo ip route add 10.20.0.0/16 via 192.168.1.1 dev eth0
sudo ip route add default via 192.168.1.1 dev eth0
sudo ip route del 10.20.0.0/16 via 192.168.1.1

Correct gateway syntax

sudo ip route add default via 192.168.1.1 dev eth0

The following is not an address command and is incorrect:

# Incorrect
ip addr add default via 192.168.1.1

What is IP forwarding?

IP forwarding allows a Linux host to forward packets received on one interface toward another destination, acting as a router.

sysctl net.ipv4.ip_forward
sudo sysctl -w net.ipv4.ip_forward=1

Persistent example:

# /etc/sysctl.d/99-router.conf
net.ipv4.ip_forward = 1
sudo sysctl --system
Warning

Forwarding alone is not a complete router setup. You may also need firewall forwarding policies, NAT, routes, and security controls.

Troubleshooting workflow

ip -br link
ip -br addr
ip route
ip route get 1.1.1.1
ping -c 4 192.168.1.1
ping -c 4 1.1.1.1
getent hosts example.com
ss -lntup

Interpretation:

  1. If the interface is down, fix the link.
  2. If there is no IP, check DHCP/static configuration.
  3. If there is no route, check the gateway.
  4. If IP connectivity works but names fail, check DNS.
  5. If the host is reachable but the application is not, check listening ports, firewall, and service health.

Common mistakes

Best practices

Interview questions

  1. What is the difference between an IP address, subnet, and gateway?
  2. What does /24 mean?
  3. How do you add a default route?
  4. What is IP forwarding?
  5. How do you separate a DNS problem from a routing problem?
  6. What is the difference between a MAC address and an IP address?

Networking cheat sheet

Goal Command
Show links ip -br link
Show addresses ip -br addr
Show routes ip route
Route decision ip route get 8.8.8.8
Add address sudo ip addr add IP/PREFIX dev IFACE
Add default route sudo ip route add default via GATEWAY dev IFACE
Show listening ports ss -lntup
Test name resolution getent hosts name

8. DNS and name resolution

What is DNS?

The Domain Name System maps names to data such as IPv4 addresses (A), IPv6 addresses (AAAA), mail servers (MX), aliases (CNAME), and service records.

/etc/hosts

What is it?

A local static hostname mapping file.

Example

127.0.0.1       localhost
192.168.1.11    db db.internal.example
192.168.1.10    app app.internal.example

Safe ways to add an entry

sudo sh -c 'printf "%s\n" "192.168.1.11 db" >> /etc/hosts'
Warning

sudo echo "..." >> /etc/hosts usually does not elevate the shell redirection. Use sudo tee -a or sudo sh -c.

printf '%s
' '192.168.1.11 db' | sudo tee -a /etc/hosts

/etc/resolv.conf

What is it?

It describes resolver settings such as DNS name servers and search domains.

search internal.example
nameserver 192.168.1.100
nameserver 1.1.1.1
options timeout:2 attempts:3
Note

On many systems /etc/resolv.conf is generated by NetworkManager, systemd-resolved, DHCP, or a cloud agent. Direct edits may be overwritten.

DNS resolution order

Linux name resolution is controlled by the Name Service Switch configuration, usually /etc/nsswitch.conf.

grep '^hosts:' /etc/nsswitch.conf

Example:

hosts: files dns

This commonly means:

  1. Check local files such as /etc/hosts.
  2. If no match is found, query configured DNS resolution services.

The actual order can contain additional mechanisms such as resolve, myhostname, mdns, or others.

Application asks for db.internal.example
                |
                v
      Name Service Switch rules
                |
       +--------+---------+
       |                  |
   /etc/hosts          DNS resolver
       |                  |
       +--------+---------+
                |
             IP address

nslookup

What is it?

A DNS query and troubleshooting tool.

nslookup example.com
nslookup example.com 192.168.1.100
nslookup -type=MX example.com

dig

What is it?

A detailed DNS query tool preferred for many DNS investigations.

dig example.com
dig A example.com
dig AAAA example.com
dig MX example.com
dig @192.168.1.100 db.internal.example
dig +short example.com
dig +trace example.com

getent hosts

dig and nslookup query DNS, but applications may follow the system's complete NSS resolution order. Use getent to test closer to normal application resolution:

getent hosts db
getent ahosts example.com

What if two DNS records use the same name?

Common mistakes

Best practices

Interview questions

  1. What is the role of /etc/nsswitch.conf in name resolution?
  2. What is the difference between /etc/hosts and DNS?
  3. Why might /etc/resolv.conf changes disappear?
  4. What is the difference between dig, nslookup, and getent hosts?
  5. Explain A, AAAA, CNAME, and MX records.

DNS cheat sheet

cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf
getent hosts example.com
nslookup example.com
dig example.com
dig +short example.com
dig @DNS_SERVER name
dig +trace example.com

9. Java and Java build tools

Java execution model

MyClass.java --javac--> MyClass.class bytecode --JVM--> machine execution

                      packaged into JAR/WAR/EAR when required

JDK, JRE, and JVM

Component Meaning Contains/does
JVM Java Virtual Machine Executes Java bytecode and manages runtime services such as memory
JRE Java Runtime Environment JVM plus runtime libraries required to run Java applications
JDK Java Development Kit Runtime plus development tools such as javac, jar, and javadoc
Note

Modern Java distributions may package runtime components differently, but the conceptual distinction remains useful: developers need compilation tools; a runtime executes bytecode.

javac

What is it?

The Java compiler. It compiles .java source files into .class bytecode.

javac MyClass.java
javac -d out src/com/example/MyClass.java
Warning

The source extension is .java, not .javac.

Expected result: MyClass.class or the package directory structure under out/.

java

Runs a compiled class or executable JAR.

java MyClass
java -cp out com.example.MyClass
java -jar myapp.jar
java -Xms256m -Xmx1g -jar myapp.jar

jar

Creates, lists, extracts, and updates Java archives.

jar --create --file myapp.jar -C out .
jar --list --file myapp.jar
jar --extract --file myapp.jar
jar --create --file myapp.jar --main-class com.example.Main -C out .

Traditional short form:

jar cf myapp.jar -C out .
jar tf myapp.jar
jar xf myapp.jar

javadoc

Generates HTML API documentation from Java source documentation comments.

javadoc -d docs src/com/example/*.java

Expected result: HTML files under docs/, including an index page.

JAR vs WAR vs EAR

Package Full name Typical content Typical use
JAR Java Archive Classes, resources, metadata, sometimes dependencies Libraries and standalone applications
WAR Web Application Archive Web application classes, libraries, web resources, deployment metadata Servlet containers/application servers
EAR Enterprise Application Archive Multiple enterprise modules such as WARs and EJB JARs Larger Jakarta EE deployments

Build tools

Maven

Maven uses a project model, conventions, dependency coordinates, lifecycle phases, and commonly a pom.xml file.

mvn clean
mvn test
mvn package
mvn verify
mvn install
mvn dependency:tree

Minimal pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>1.0.0</version>
</project>

Gradle

Gradle uses a programmable build model, commonly Groovy or Kotlin DSL.

./gradlew clean
./gradlew test
./gradlew build
./gradlew dependencies

Simple Groovy build.gradle:

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0.0'

repositories {
    mavenCentral()
}

test {
    useJUnitPlatform()
}

Ant

Ant is task-oriented and usually configured through build.xml. It gives detailed control but has fewer conventions and does not provide dependency management by itself in the same way as Maven or Gradle.

ant
ant clean
ant compile
ant jar

Build-tool comparison

Tool Style Main file Strength
Maven Convention and lifecycle pom.xml Predictable structure and dependency ecosystem
Gradle Programmable and incremental build.gradle / .kts Flexibility and performance features
Ant Explicit tasks build.xml Fine-grained legacy/custom build control

Common mistakes

Best practices

Interview questions

  1. Explain the difference between JDK, JRE, and JVM.
  2. What does javac produce?
  3. Compare JAR, WAR, and EAR.
  4. Explain Maven's clean, test, package, verify, and install phases.
  5. Why use Maven or Gradle wrappers?

Java cheat sheet

javac MyClass.java
java MyClass
jar --create --file app.jar -C out .
jar --list --file app.jar
javadoc -d docs src/*.java
mvn clean verify
./gradlew clean build

10. Jenkins

What is Jenkins?

Jenkins is an open-source automation server used to implement continuous integration and continuous delivery workflows. It can fetch code, build it, test it, scan it, package it, publish artifacts, and deploy it.

Why do we use it?

A repeatable pipeline reduces manual errors and gives every change the same build and validation process.

Developer -> Git push -> Jenkins Pipeline
                         | Checkout
                         | Build
                         | Test
                         | Scan
                         | Package
                         | Publish
                         | Deploy
                         v
                    Environment

Architecture

Controller

The Jenkins controller stores configuration, schedules jobs, provides the UI/API, and coordinates work.

Agent

An agent provides executors and a workspace where build steps run. Agents may be VMs, physical hosts, Docker containers, or ephemeral Kubernetes Pods.

Note

Older material often says “master/slave.” Current Jenkins terminology is controller/agent.

                   +----------------------+
Git/Webhook ------>| Jenkins Controller   |
                   | Queue, UI, Scheduling|
                   +----------+-----------+
                              |
                 +------------+-------------+
                 |                          |
        +--------v---------+       +--------v---------+
        | Linux Agent      |       | Kubernetes Agent |
        | Maven, Docker    |       | Ephemeral Pod    |
        +------------------+       +------------------+

Jobs, builds, pipelines, and plugins

Term Meaning
Job Saved automation configuration
Build One execution of a job
Pipeline Stages and steps describing delivery workflow as code
Plugin Extension adding SCM, credentials, UI, integrations, steps, and other features
Artifact Immutable file produced by a build, such as JAR, ZIP, image metadata, or report

Declarative Pipeline example

pipeline {
    agent any

    options {
        timestamps()
        disableConcurrentBuilds()
    }

    environment {
        APP_NAME = 'java-maven-app'
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Build and Test') {
            steps {
                sh './mvnw clean verify'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }

        stage('Package') {
            steps {
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
            }
        }

        stage('Build Image') {
            steps {
                sh 'docker build -t registry.example.com/myapp:${BUILD_NUMBER} .'
            }
        }

        stage('Push Image') {
            steps {
                withCredentials([usernamePassword(
                    credentialsId: 'registry-credentials',
                    usernameVariable: 'REGISTRY_USER',
                    passwordVariable: 'REGISTRY_PASSWORD'
                )]) {
                    sh '''
                      set +x
                      printf '%s' "$REGISTRY_PASSWORD" | \
                        docker login registry.example.com \
                        --username "$REGISTRY_USER" --password-stdin
                      docker push registry.example.com/myapp:${BUILD_NUMBER}
                    '''
                }
            }
        }

        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                sh 'kubectl set image deployment/myapp myapp=registry.example.com/myapp:${BUILD_NUMBER}'
                sh 'kubectl rollout status deployment/myapp --timeout=5m'
            }
        }
    }

    post {
        always {
            cleanWs()
        }
        failure {
            echo 'Pipeline failed. Review the failing stage and logs.'
        }
    }
}

Pipeline flow

  1. Webhook triggers Jenkins after a Git push.
  2. Jenkins queues the build.
  3. An agent receives an executor and workspace.
  4. Code is checked out.
  5. Build and tests run.
  6. Artifact or image is produced and versioned.
  7. Credentials are injected only around the step that needs them.
  8. Deployment runs for approved branches/environments.
  9. Rollout status and tests confirm success.

Common mistakes

Best practices

Interview questions

  1. Explain Jenkins controller and agent responsibilities.
  2. What is the difference between a job and a build?
  3. Why use Pipeline as Code?
  4. How do you protect secrets in a Jenkins pipeline?
  5. How would you design zero-downtime deployment and rollback?
  6. Why should builds not normally run on the controller?

Jenkins cheat sheet

Jenkinsfile -> pipeline definition
agent      -> where stages run
stage      -> logical phase
steps      -> commands/actions
post       -> actions after stage/pipeline result
credentials-> inject securely for limited scope
artifact   -> immutable build output

11. Docker

What is Docker?

Docker is a container platform. A container packages an application process with its userspace files and dependencies while sharing the host kernel.

Why do we use it?

Containers make development, CI, and deployment environments more consistent and reproducible.

Dockerfile --docker build--> Image --docker run--> Container
                                      |
                                      +--> Volume for persistent data
                                      +--> Network for communication

Core concepts

Image

A read-only, layered application package used to create containers.

Container

A running or stopped instance created from an image. Writable container layers are normally ephemeral.

Volume

Docker-managed persistent storage independent of one container's lifecycle.

Network

A communication boundary that lets containers reach each other and external systems. On a user-defined network, containers can commonly resolve each other by name.

Dockerfile

A file containing instructions used to build an image.

Docker Compose

A YAML-based model for running a multi-container application with services, networks, volumes, configuration, and dependencies. Modern command syntax is docker compose.

Common Docker commands

Information

docker version
docker info
docker system df

Images

docker image ls
docker pull nginx:alpine
docker build -t myapp:1.0.0 .
docker tag myapp:1.0.0 registry.example.com/myapp:1.0.0
docker push registry.example.com/myapp:1.0.0
docker image inspect myapp:1.0.0
docker image rm myapp:1.0.0

Containers

docker run --name web -d -p 8080:80 nginx:alpine
docker container ls
docker container ls -a
docker logs web
docker logs -f --tail 100 web
docker exec -it web sh
docker inspect web
docker stop web
docker start web
docker restart web
docker rm web

Command breakdown:

docker run --name web -d -p 8080:80 nginx:alpine

Volumes

docker volume create app-data
docker volume ls
docker volume inspect app-data
docker run -d --name db -v app-data:/var/lib/postgresql/data postgres:17
docker volume rm app-data

Networks

docker network create app-network
docker network ls
docker network inspect app-network
docker run -d --name web --network app-network nginx:alpine
docker network connect app-network another-container
docker network disconnect app-network another-container
docker network rm app-network

Cleanup

docker container prune
docker image prune
docker volume prune
docker network prune
docker system prune
Warning

Prune commands delete unused objects. Review what is considered unused before running them, especially volumes.

Production Dockerfile example

# syntax=docker/dockerfile:1

FROM eclipse-temurin:21-jdk AS build
WORKDIR /workspace
COPY .mvn/ .mvn/
COPY mvnw pom.xml ./
RUN ./mvnw -q -DskipTests dependency:go-offline
COPY src/ src/
RUN ./mvnw -q clean package -DskipTests

FROM eclipse-temurin:21-jre
RUN useradd --system --uid 10001 --create-home appuser
WORKDIR /app
COPY --from=build /workspace/target/*.jar /app/app.jar
USER 10001
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

Docker Compose example

services:
  app:
    build:
      context: .
    image: example/myapp:1.0.0
    restart: unless-stopped
    environment:
      DATABASE_HOST: db
      DATABASE_PORT: "5432"
      DATABASE_NAME: app
      DATABASE_USER: app
      DATABASE_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - backend

  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

volumes:
  db_data:

networks:
  backend:
    driver: bridge

secrets:
  db_password:
    file: ./secrets/db_password.txt
docker compose config
docker compose build
docker compose up -d
docker compose ps
docker compose logs -f app
docker compose exec app sh
docker compose pull
docker compose up -d --remove-orphans
docker compose down

Bind mount vs volume

Storage Example Best suited for
Bind mount ./config:/app/config:ro Development source or explicit host-managed paths
Named volume db_data:/var/lib/postgresql/data Persistent application data managed by Docker
tmpfs memory-backed mount Temporary sensitive or high-speed ephemeral data

Common mistakes

Best practices

Interview questions

  1. What is the difference between an image and a container?
  2. What is the difference between a bind mount and a named volume?
  3. Explain EXPOSE versus publishing with -p.
  4. Why use a multi-stage build?
  5. How do containers communicate by name in Compose?
  6. What happens to a container's writable layer when it is deleted?

Docker cheat sheet

docker build -t app:1.0.0 .
docker run --name app -d -p 8080:8080 app:1.0.0
docker ps -a
docker logs -f app
docker exec -it app sh
docker inspect app
docker stop app && docker rm app
docker compose config
docker compose up -d
docker compose logs -f
docker compose down

12. Kubernetes

What is Kubernetes?

Kubernetes is a platform for deploying and operating containerized applications across a cluster. It schedules workloads, maintains desired state, provides service discovery, performs controlled rollouts, and replaces failed workload instances through controllers.

Why do we use it?

A production application may need multiple replicas, rolling updates, service discovery, configuration injection, autoscaling, self-healing, and scheduling across many machines. Kubernetes provides APIs and controllers for these concerns.

Cluster architecture

                         Control Plane
       +------------------------------------------------+
       | API Server | Scheduler | Controller Manager    |
       |            | etcd (cluster state)              |
       +----------------------+-------------------------+
                              |
                     Kubernetes API
                              |
          +-------------------+-------------------+
          |                                       |
 +--------v---------+                    +--------v---------+
 | Worker Node 1    |                    | Worker Node 2    |
 | kubelet          |                    | kubelet          |
 | container runtime|                    | container runtime|
 | kube-proxy/CNI   |                    | kube-proxy/CNI   |
 | Pods             |                    | Pods             |
 +------------------+                    +------------------+

Cluster

A set of control-plane and worker components managed as one Kubernetes environment.

Control plane

Coordinates the cluster. Older notes may call this the “master,” but control plane is the current term.

Worker node

A machine that runs application Pods and node components.

Node

A registered machine in the cluster. Control-plane machines can also be nodes, but production workloads are commonly placed on workers.

Basic kubectl commands

kubectl cluster-info
kubectl get nodes
kubectl get namespaces
kubectl get all -n default
kubectl api-resources
kubectl explain deployment.spec

Kubernetes YAML syntax

YAML uses indentation to represent structure. Use spaces, not tabs.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - name: http
              containerPort: 80

Required object fields usually include:

Warning

The field is matchLabels, not matchLables. Labels in a controller selector must match labels in the Pod template.

Pod

Definition

The smallest deployable Kubernetes unit. A Pod contains one or more tightly coupled containers sharing network and specified storage.

Why use it?

Kubernetes schedules containers as Pods. A sidecar can share the same Pod when it must share lifecycle and localhost networking with the main container.

YAML

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
    tier: frontend
spec:
  containers:
    - name: nginx
      image: nginx:1.27-alpine
      ports:
        - name: http
          containerPort: 80
      resources:
        requests:
          cpu: 50m
          memory: 64Mi
        limits:
          memory: 128Mi
      readinessProbe:
        httpGet:
          path: /
          port: http
        initialDelaySeconds: 2
        periodSeconds: 5

Commands

kubectl apply -f pod.yaml
kubectl get pods -o wide
kubectl describe pod nginx
kubectl logs nginx
kubectl exec -it nginx -- sh
kubectl delete pod nginx --wait=true

Diagram

Pod: nginx
+----------------------------------+
| Shared network namespace         |
| IP: 10.x.x.x                     |
|                                  |
| +------------------------------+ |
| | nginx container :80          | |
| +------------------------------+ |
+----------------------------------+

Common mistakes

Best practices

Use Deployments, StatefulSets, Jobs, or other controllers for production workloads. Keep containers in one Pod only when they need tight lifecycle or data sharing.

ReplicationController

Definition

A legacy controller that maintains a specified number of Pod replicas.

YAML

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
spec:
  replicas: 3
  selector:
    app: myapp
    tier: frontend
  template:
    metadata:
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine

Commands

kubectl apply -f rc-definition.yml
kubectl get replicationcontrollers
kubectl describe replicationcontroller myapp-rc
kubectl scale replicationcontroller myapp-rc --replicas=5
kubectl delete replicationcontroller myapp-rc

Best practice

Learn it for legacy environments and interviews, but use Deployments/ReplicaSets for new stateless applications.

ReplicaSet

Definition

A controller that maintains a desired number of matching Pod replicas. It supports set-based label selectors.

YAML

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      tier: frontend
  template:
    metadata:
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine

Commands

kubectl apply -f replicaset-definition.yml
kubectl get replicasets
kubectl describe replicaset myapp-replicaset
kubectl scale replicaset myapp-replicaset --replicas=6
kubectl edit replicaset myapp-replicaset
kubectl delete replicaset myapp-replicaset

Diagram

ReplicaSet desired replicas: 3
            |
     +------+------+ 
     |      |      |
   Pod 1  Pod 2  Pod 3

Common mistake

Editing a ReplicaSet owned by a Deployment. The Deployment controller may overwrite or replace it.

Best practice

Use a Deployment to manage ReplicaSets for stateless applications.

Deployment

Definition

A controller that manages ReplicaSets and declarative updates for stateless Pods.

YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: myapp
      tier: frontend
  template:
    metadata:
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - name: http
              containerPort: 80
          readinessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 2
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              memory: 128Mi

Commands

kubectl apply -f deployment.yml
kubectl get deployments
kubectl describe deployment myapp-deployment
kubectl get replicasets
kubectl get pods -l app=myapp
kubectl scale deployment myapp-deployment --replicas=6
kubectl set image deployment/myapp-deployment nginx=nginx:1.28-alpine
kubectl rollout status deployment/myapp-deployment
kubectl rollout history deployment/myapp-deployment
kubectl rollout undo deployment/myapp-deployment
kubectl delete deployment myapp-deployment

Diagram

Deployment
   |
   +--> ReplicaSet revision 2 (desired: 3)
   |       +--> Pod A
   |       +--> Pod B
   |       +--> Pod C
   |
   +--> ReplicaSet revision 1 (scaled down, retained for rollback)

Best practices

Namespace

Definition

A logical scope for names and many policies. Namespaces help separate teams, environments, or applications, but are not automatically a complete security boundary.

YAML

apiVersion: v1
kind: Namespace
metadata:
  name: production

Commands

kubectl apply -f namespace.yaml
kubectl get namespaces
kubectl get pods -n production
kubectl config set-context --current --namespace=production

Best practices

Apply RBAC, NetworkPolicies, ResourceQuotas, LimitRanges, and naming standards per namespace.

ConfigMap

Definition

Stores non-secret configuration as key-value data or files.

YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  application.properties: |
    server.port=8080
    feature.enabled=true

Commands

kubectl apply -f configmap.yaml
kubectl get configmap myapp-config -o yaml
kubectl create configmap example --from-literal=LOG_LEVEL=info --dry-run=client -o yaml

Pod usage

envFrom:
  - configMapRef:
      name: myapp-config

Best practice

Do not store passwords, tokens, or private keys in ConfigMaps.

Secret

Definition

Stores sensitive values for use by workloads. Kubernetes Secrets are base64-encoded in manifests and require encryption, RBAC, and external secret controls for strong protection.

YAML

apiVersion: v1
kind: Secret
metadata:
  name: myapp-secret
type: Opaque
stringData:
  DATABASE_USERNAME: app
  DATABASE_PASSWORD: replace-through-secret-management

Commands

kubectl apply -f secret.yaml
kubectl create secret generic myapp-secret \
  --from-literal=DATABASE_USERNAME=app \
  --from-literal=DATABASE_PASSWORD='strong-value' \
  --dry-run=client -o yaml
kubectl get secret myapp-secret

Best practices

Service

Definition

A Service provides a stable virtual address and DNS name for a changing set of selected Pods.

Client -> Service virtual IP/name -> Endpoint Pods
                                  +-> Pod A
                                  +-> Pod B
                                  +-> Pod C

ClusterIP

Default service type. Exposes the service inside the cluster.

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: ClusterIP
  selector:
    app: myapp
    tier: frontend
  ports:
    - name: http
      port: 80
      targetPort: http

NodePort

Exposes a port on each node in addition to the ClusterIP behavior. The default allocated range is commonly 30000-32767, subject to cluster configuration.

apiVersion: v1
kind: Service
metadata:
  name: myapp-nodeport
spec:
  type: NodePort
  selector:
    app: myapp
    tier: frontend
  ports:
    - name: http
      port: 80
      targetPort: http
      nodePort: 30008
Client -> NodeIP:30008 -> Service:80 -> Pod:80

LoadBalancer

Requests an external load balancer from a supported cloud provider or load-balancer implementation.

apiVersion: v1
kind: Service
metadata:
  name: myapp-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: myapp
    tier: frontend
  ports:
    - name: http
      port: 80
      targetPort: http

Service commands

kubectl apply -f service-definition.yml
kubectl get services
kubectl describe service myapp
kubectl get endpointslices -l kubernetes.io/service-name=myapp
kubectl delete service myapp

Service mistakes

kubectl command reference

kubectl apply

Creates or updates resources declaratively from files.

kubectl apply -f deployment.yml
kubectl apply -f k8s/
kubectl diff -f k8s/

kubectl create

Creates a resource. Useful for imperative commands and generating YAML.

kubectl create namespace demo
kubectl run hello-minikube --image=nginx:1.27-alpine
kubectl create deployment web --image=nginx:1.27-alpine
kubectl create deployment web --image=nginx:1.27-alpine --dry-run=client -o yaml

kubectl run creates a Pod by default in modern Kubernetes. For a managed application, create a Deployment instead of relying on a bare Pod.

kubectl delete

Deletes resources.

kubectl delete -f deployment.yml
kubectl delete pod webapp --wait=true
kubectl delete deployment web

kubectl edit

Opens the live object in an editor.

kubectl edit deployment myapp
kubectl edit rs new-replica-set

Use for emergency changes; update the source manifest afterward to prevent configuration drift.

kubectl replace

Replaces an existing object from a complete manifest.

kubectl replace -f replicaset-definition.yml

It is less forgiving than apply because the supplied file is treated as the replacement representation. Declarative Git workflows normally prefer apply or server-side apply.

kubectl scale

Changes replica count.

kubectl scale deployment myapp --replicas=6
kubectl scale --replicas=6 -f deployment.yml

kubectl describe

Shows detailed resource state and events.

kubectl describe pod myapp-abc123
kubectl describe deployment myapp

kubectl logs

Reads container logs.

kubectl logs pod-name
kubectl logs -f pod-name
kubectl logs pod-name -c sidecar
kubectl logs pod-name --previous
kubectl logs -l app=myapp --tail=100 --prefix

kubectl exec

Runs a command in an existing container.

kubectl exec pod-name -- env
kubectl exec -it pod-name -- sh
kubectl exec -it pod-name -c app -- sh
Tip

-- separates kubectl options from the command executed inside the container.

Rollout and versioning

Recreate strategy

Old Pods are terminated before new Pods are created.

strategy:
  type: Recreate

Use when old and new versions cannot run together, but plan for downtime.

RollingUpdate strategy

Kubernetes gradually adds new Pods and removes old Pods.

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 0
    maxSurge: 1
Old:  v1 v1 v1
Step: v1 v1 v1 v2
Step: v1 v1 v2 v2
New:  v2 v2 v2

A rolling update is not automatically zero-downtime. The application also needs readiness checks, enough capacity, compatible dependencies, graceful shutdown, and suitable traffic handling.

Rollout commands

kubectl rollout status deployment/myapp
kubectl rollout history deployment/myapp
kubectl rollout history deployment/myapp --revision=2
kubectl rollout undo deployment/myapp
kubectl rollout undo deployment/myapp --to-revision=2
kubectl rollout pause deployment/myapp
kubectl rollout resume deployment/myapp
kubectl rollout restart deployment/myapp
Note

Older examples use kubectl create -f deployment.yml --record. The --record flag is deprecated/removed in modern workflows. Use version control, annotations, CI/CD metadata, and immutable image references for change history.

Microservices architecture on Kubernetes

                         Internet
                            |
                    Ingress / Gateway
                            |
           +----------------+----------------+
           |                                 |
   frontend Service                    api Service
           |                                 |
      frontend Pods            +-------------+-------------+
                               |                           |
                        orders Service             users Service
                               |                           |
                         orders Pods                 users Pods
                               |                           |
                        Database/Queue             Database/Cache

Typical supporting resources:

Kubernetes production checklist

Kubernetes common mistakes

Kubernetes interview questions

  1. Explain control plane, worker node, Pod, ReplicaSet, and Deployment.
  2. Why use a Deployment instead of a bare Pod?
  3. What happens if a Pod managed by a ReplicaSet is deleted?
  4. Explain port, targetPort, and nodePort.
  5. Compare ClusterIP, NodePort, and LoadBalancer.
  6. How does a Deployment perform a rolling update?
  7. What is required for a truly low-downtime rollout?
  8. What is the difference between ConfigMap and Secret?
  9. What happens when a Service selector matches no Pods?
  10. How do readiness and liveness probes differ?
  11. Why are resource requests important to the scheduler?
  12. What is configuration drift in Kubernetes?

Kubernetes cheat sheet

kubectl cluster-info
kubectl get nodes
kubectl get all -A
kubectl apply -f k8s/
kubectl get pods -o wide
kubectl describe pod POD
kubectl logs -f POD
kubectl exec -it POD -- sh
kubectl scale deployment APP --replicas=6
kubectl set image deployment/APP CONTAINER=IMAGE:TAG
kubectl rollout status deployment/APP
kubectl rollout history deployment/APP
kubectl rollout undo deployment/APP
kubectl delete -f k8s/

13. Ansible

What is Ansible?

Ansible is an automation tool for configuration management, application deployment, orchestration, and repeatable administrative tasks. It commonly connects over SSH and applies modules to managed hosts.

Why do we use it?

Instead of manually installing and configuring Nginx on 50 servers, you describe the desired configuration once and apply it consistently.

Ansible control node
        |
        | SSH / supported connection
        v
+-------+-------+-------+
| Web 1 | Web 2 | DB 1  |
+-------+-------+-------+

Inventory

An inventory defines managed hosts and groups.

# inventory.ini
[web]
web1 ansible_host=192.168.1.21
web2 ansible_host=192.168.1.22

[db]
db1 ansible_host=192.168.1.31

[all:vars]
ansible_user=automation
ansible_ssh_private_key_file=~/.ssh/automation
ansible-inventory -i inventory.ini --graph
ansible all -i inventory.ini -m ansible.builtin.ping

Playbook

A playbook is a YAML automation blueprint containing one or more plays. Each play maps hosts to tasks.

---
- name: Configure web servers
  hosts: web
  become: true
  gather_facts: true

  tasks:
    - name: Install Nginx
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Start and enable Nginx
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true
ansible-playbook -i inventory.ini web.yml
ansible-playbook -i inventory.ini web.yml --check --diff
ansible-playbook -i inventory.ini web.yml --syntax-check

Modules

Modules perform actions such as package installation, file copying, user management, service control, cloud operations, and API calls.

- name: Create application directory
  ansible.builtin.file:
    path: /srv/myapp
    state: directory
    owner: myapp
    group: myapp
    mode: '0750'

Prefer a purpose-built module over shell or command when one exists because modules better support idempotence and structured results.

Variables

Variables make automation reusable.

---
- name: Demonstrate variables
  hosts: web
  vars:
    app_name: myapp
    app_port: 8080

  tasks:
    - name: Show application port
      ansible.builtin.debug:
        msg: "{{ app_name }} listens on {{ app_port }}"

Variable sources include inventory, group variables, host variables, role defaults/vars, play vars, facts, registered results, and extra vars. Precedence matters; keep the design simple.

Facts

Facts are collected information about managed hosts.

- name: Show operating system
  ansible.builtin.debug:
    msg: "{{ ansible_facts.distribution }} {{ ansible_facts.distribution_version }}"
ansible web1 -i inventory.ini -m ansible.builtin.setup

Templates

Templates use Jinja to generate files from variables.

# templates/myapp.conf.j2
server {
    listen 80;
    server_name {{ server_name }};

    location / {
        proxy_pass http://127.0.0.1:{{ app_port }};
    }
}
- name: Install Nginx virtual host
  ansible.builtin.template:
    src: myapp.conf.j2
    dest: /etc/nginx/conf.d/myapp.conf
    owner: root
    group: root
    mode: '0644'
  notify: Reload Nginx

Handlers

Handlers run when notified by a changed task, commonly to restart or reload a service.

handlers:
  - name: Reload Nginx
    ansible.builtin.service:
      name: nginx
      state: reloaded

If the template does not change, the handler is not notified.

Roles

Roles organize tasks, handlers, templates, files, variables, and defaults in a reusable structure.

roles/
└── webserver/
    ├── defaults/main.yml
    ├── files/
    ├── handlers/main.yml
    ├── tasks/main.yml
    ├── templates/
    ├── vars/main.yml
    └── meta/main.yml
---
- name: Apply webserver role
  hosts: web
  become: true
  roles:
    - webserver

Practical playbook: deploy a static site

---
- name: Deploy static website
  hosts: web
  become: true
  vars:
    web_root: /var/www/example

  tasks:
    - name: Install Nginx
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Create web root
      ansible.builtin.file:
        path: "{{ web_root }}"
        state: directory
        owner: root
        group: root
        mode: '0755'

    - name: Publish website
      ansible.builtin.copy:
        src: site/
        dest: "{{ web_root }}/"
        owner: root
        group: root
        mode: '0644'
      notify: Reload Nginx

    - name: Install site configuration
      ansible.builtin.template:
        src: nginx-site.conf.j2
        dest: /etc/nginx/conf.d/example.conf
        owner: root
        group: root
        mode: '0644'
        validate: nginx -t -c %s
      notify: Reload Nginx

    - name: Ensure Nginx is running and enabled
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true

  handlers:
    - name: Reload Nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded
Note

The exact Nginx validation command and configuration location can differ by distribution. Test the template validation approach in the target OS.

Ansible Vault

Encrypt sensitive Ansible data rather than committing it as plaintext.

ansible-vault create group_vars/production/vault.yml
ansible-vault edit group_vars/production/vault.yml
ansible-playbook -i inventory.ini site.yml --ask-vault-pass

For production automation, integrate Vault password retrieval with a secure secret-management method rather than sharing a password manually.

Common mistakes

Best practices

Interview questions

  1. What is an inventory?
  2. What is the difference between a play, playbook, task, and module?
  3. Explain Ansible idempotence.
  4. When does a handler run?
  5. What is the difference between copy and template?
  6. Why are roles useful?
  7. How do you protect secrets?
  8. Why prefer modules over shell commands?

Ansible cheat sheet

ansible-inventory -i inventory.ini --graph
ansible all -i inventory.ini -m ansible.builtin.ping
ansible-playbook -i inventory.ini site.yml --syntax-check
ansible-playbook -i inventory.ini site.yml --check --diff
ansible-playbook -i inventory.ini site.yml
ansible-vault edit secret.yml

14. Terraform

What is Terraform?

Terraform is an Infrastructure as Code tool. You describe infrastructure in configuration files, Terraform compares the desired configuration with known state and provider APIs, and then proposes or applies changes.

Why do we use it?

Infrastructure becomes reviewable, repeatable, version-controlled, and easier to reproduce across environments.

Terraform configuration (.tf)
             |
       terraform plan
             |
     Desired vs current state
             |
       terraform apply
             |
     Cloud/provider APIs
             |
      Infrastructure resources

Providers

A provider plugin communicates with an external API such as AWS, Azure, OCI, Google Cloud, Kubernetes, or GitHub.

terraform {
  required_version = ">= 1.8.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}
Note

Choose provider and Terraform constraints according to versions tested by your organization. Run terraform init -upgrade deliberately, review lock-file changes, and test upgrades.

Resources

A resource declares an infrastructure object Terraform should manage.

resource "aws_s3_bucket" "artifacts" {
  bucket = var.artifact_bucket_name

  tags = {
    Name        = "Build artifacts"
    Environment = var.environment
  }
}

The resource address is aws_s3_bucket.artifacts.

Variables

Variables make configurations reusable.

variable "aws_region" {
  description = "AWS region for resources"
  type        = string
  default     = "ap-south-1"
}

variable "environment" {
  description = "Deployment environment"
  type        = string

  validation {
    condition     = contains(["dev", "staging", "production"], var.environment)
    error_message = "Environment must be dev, staging, or production."
  }
}

Example terraform.tfvars:

environment          = "dev"
artifact_bucket_name = "replace-with-globally-unique-name"

Do not commit secrets in .tfvars files.

Outputs

Outputs expose useful values after apply and can be consumed by other automation.

output "artifact_bucket_arn" {
  description = "ARN of the artifact bucket"
  value       = aws_s3_bucket.artifacts.arn
}
terraform output
terraform output -raw artifact_bucket_arn

Modules

A module is a reusable group of Terraform configuration. The current directory is the root module; called modules are child modules.

module "network" {
  source = "./modules/network"

  environment = var.environment
  vpc_cidr    = "10.20.0.0/16"
}

Example structure:

terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── versions.tf
├── environments/
└── modules/
    └── network/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

State

Terraform state maps configuration resource addresses to real infrastructure objects and stores attributes needed for planning.

Default local state:

terraform.tfstate
Warning

State can contain sensitive values. Do not commit it to Git. Protect it with access controls, encryption, backups/versioning, and state locking where supported.

Backend

A backend determines where Terraform stores state and performs related operations such as locking.

Example S3 backend configuration:

terraform {
  backend "s3" {
    bucket       = "company-terraform-state"
    key          = "dev/network/terraform.tfstate"
    region       = "ap-south-1"
    encrypt      = true
    use_lockfile = true
  }
}

Backend authentication should come from secure environment/identity configuration, not hard-coded credentials.

Note

Backend features and arguments evolve. Validate the configuration against the Terraform version and backend documentation used by your team.

Terraform command workflow

terraform fmt

Formats Terraform files.

terraform fmt
terraform fmt -recursive
terraform fmt -check -recursive

terraform init

Initializes a working directory, configures the backend, downloads providers, and downloads modules.

terraform init
terraform init -upgrade
terraform init -reconfigure
terraform init -migrate-state

terraform validate

Checks configuration syntax and internal consistency after initialization.

terraform validate

terraform plan

Builds an execution plan showing proposed changes.

terraform plan
terraform plan -var-file=dev.tfvars
terraform plan -out=tfplan
terraform show tfplan

Typical symbols:

terraform apply

Executes an approved plan.

terraform apply
terraform apply tfplan

Applying a saved plan is safer in CI because the reviewed plan is the one executed, provided the plan is stored and handled securely and has not become invalid.

terraform destroy

Plans and destroys resources managed by the configuration.

terraform plan -destroy
terraform destroy
Warning

terraform destroy can remove production infrastructure and data. Use access controls, protected workflows, backups, and explicit approvals.

AWS example: VPC and EC2 instance

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

data "aws_ami" "linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_vpc" "main" {
  cidr_block           = "10.20.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "${var.environment}-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.20.1.0/24"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.environment}-public"
  }
}

resource "aws_security_group" "web" {
  name        = "${var.environment}-web"
  description = "Allow application traffic"
  vpc_id      = aws_vpc.main.id

  ingress {
    description = "HTTP"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web" {
  ami                    = data.aws_ami.linux.id
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web.id]

  tags = {
    Name        = "${var.environment}-web"
    Environment = var.environment
  }
}
Warning

This is a learning example, not a complete production network. It omits an Internet gateway, routes, private subnets, restricted administration, load balancing, TLS, monitoring, backup, and many security controls.

Terraform workflow for teams

Developer branch
     |
terraform fmt -check
terraform validate
security/lint checks
     |
terraform plan
     |
Peer review + approval
     |
Apply saved plan using protected credentials
     |
Post-apply tests and monitoring

Common mistakes

Best practices

Interview questions

  1. What is Terraform state and why is it required?
  2. What does terraform init do?
  3. What is the difference between a provider and a resource?
  4. What is a backend?
  5. Why save a plan using -out?
  6. How do you handle configuration drift?
  7. How do modules improve infrastructure code?
  8. How do you protect sensitive state?
  9. What is the difference between terraform validate and terraform plan?
  10. How would you separate dev, staging, and production?

Terraform cheat sheet

terraform fmt -recursive
terraform init
terraform validate
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplan
terraform output
terraform state list
terraform plan -destroy
terraform destroy

15. Suggested hands-on learning path

Lab 1: Linux filesystem

  1. Create /tmp/devops-lab/{config,data,logs}.
  2. Create configuration files with touch and Vim.
  3. Copy and rename them.
  4. Search content using grep and files using find.
  5. Set ownership and permissions.
  6. Delete only the lab directory after checking pwd and ls.

Lab 2: Linux service

  1. Create a small script or Java JAR.
  2. Create a dedicated service user.
  3. Create a systemd unit.
  4. Start, enable, inspect, and follow logs.
  5. Test failure and restart behavior.

Lab 3: Networking and DNS

  1. Record ip link, ip addr, and ip route output.
  2. Use ip route get for a public address.
  3. Add a temporary /etc/hosts entry in a VM.
  4. Compare getent hosts, dig, and nslookup.
  5. Remove the test entry.

Lab 4: Java and Jenkins

  1. Create a minimal Java Maven project.
  2. Run ./mvnw clean verify.
  3. Package the JAR.
  4. Create a Jenkinsfile with checkout, test, package, and artifact stages.
  5. Add an agent rather than building on the controller.

Lab 5: Docker

  1. Create a multi-stage Dockerfile.
  2. Build a versioned image.
  3. Run it as a non-root user.
  4. Connect the application and PostgreSQL through Compose.
  5. Persist database data in a named volume.
  6. Verify logs and health.

Lab 6: Kubernetes

  1. Create a namespace.
  2. Deploy the application using a Deployment.
  3. Add ConfigMap and Secret references.
  4. Expose it through ClusterIP and test with port-forwarding.
  5. Scale to three replicas.
  6. Roll out a new immutable image tag.
  7. Inspect history and perform rollback.

Lab 7: Ansible

  1. Create two Linux VMs.
  2. Build an inventory.
  3. Test connectivity with ansible.builtin.ping.
  4. Create a role that installs and configures Nginx.
  5. Use a template and handler.
  6. Run syntax check, check mode, and actual apply.

Lab 8: Terraform

  1. Configure a remote state design for a non-production lab.
  2. Create an AWS provider configuration using a role/profile.
  3. Create a small network or S3 resource.
  4. Run format, initialize, validate, and plan.
  5. Review and apply a saved plan.
  6. Verify the resource and then destroy the lab safely.

Final learning project

Build this complete flow:

Git repository
   |
Jenkins Pipeline
   |-- test Java application
   |-- build immutable JAR
   |-- build and scan Docker image
   |-- push image to registry
   |-- update Kubernetes deployment
   |-- verify rollout and health
   |
Terraform provisions infrastructure
Ansible configures supporting Linux hosts
Monitoring confirms availability

Final production checklist


Official documentation references

Tip

Product behavior and flags can change. For production work, verify commands against the exact operating-system, Java, Jenkins, Docker, Kubernetes, Ansible, Terraform, cloud-provider, and plugin versions used in your environment.