Practice Questions

10 minute read

Practice Questions Overview

Test your understanding of the development setup concepts covered in this module. These questions range from basic recall to advanced application of knowledge.

Scoring Guide:

  • 80-100%: Excellent! Ready to move forward
  • 60-79%: Good, review specific topics
  • Below 60%: Review the module before proceeding

Part 1: Multiple Choice

Question 1

What is the minimum Go version required for Terraform provider development?

A) Go 1.18
B) Go 1.19
C) Go 1.21
D) Go 1.22

View Answer **Answer: C) Go 1.21** Plugin Framework 1.5+ requires Go 1.21 or later for generics support and other modern Go features.

Question 2

Which command initializes a new Go module?

A) go create module
B) go mod init <module-path>
C) go init module
D) go new module <path>

View Answer **Answer: B) `go mod init `** This creates a new go.mod file with the specified module path. </details> --- ### Question 3 What is the purpose of the `internal/` directory in a provider project? A) Store internal documentation B) House private packages that cannot be imported externally C) Keep internal API code D) Store provider configuration files
View Answer **Answer: B) House private packages that cannot be imported externally** The `internal/` directory is a Go convention that prevents external modules from importing packages within it, enforcing encapsulation.
--- ### Question 4 Which file contains cryptographic checksums of module dependencies? A) go.mod B) go.lock C) go.sum D) dependencies.lock
View Answer **Answer: C) go.sum** go.sum contains cryptographic checksums that ensure dependency integrity and enable reproducible builds.
--- ### Question 5 What is the recommended way to add a new dependency to a Go project? A) Manually edit go.mod B) Use `go get ` C) Use `go install ` D) Use `go download `
View Answer **Answer: B) Use `go get `** While manual editing works, `go get` is the recommended approach as it updates go.mod, go.sum, and downloads the package. </details> --- ### Question 6 Which directory contains auto-generated documentation for the provider? A) documentation/ B) docs/ C) doc/ D) manual/
View Answer **Answer: B) docs/** The docs/ directory contains auto-generated documentation created by terraform-plugin-docs tool.
--- ### Question 7 What command removes unused dependencies and adds missing ones? A) `go mod clean` B) `go mod tidy` C) `go mod prune` D) `go mod sync`
View Answer **Answer: B) `go mod tidy`** go mod tidy ensures go.mod matches the imports in your code by adding missing and removing unused dependencies.
--- ### Question 8 Where should provider examples be stored? A) tests/ B) samples/ C) examples/ D) demos/
View Answer **Answer: C) examples/** The examples/ directory is the standard location for working Terraform configuration examples.
--- ### Question 9 Which tool is used to scaffold a new Terraform provider? A) terraform-scaffold B) HashiCorp's provider template repository C) provider-init D) terraform-plugin-init
View Answer **Answer: B) HashiCorp's provider template repository** HashiCorp provides terraform-provider-scaffolding-framework, a GitHub template repository for creating new providers.
--- ### Question 10 What is the purpose of the .goreleaser.yml file? A) Release notes generation B) Multi-platform build and release automation C) Goroutine management D) Go version release tracking
View Answer **Answer: B) Multi-platform build and release automation** GoReleaser automates building binaries for multiple platforms, packaging, and GitHub release creation.
--- ## Part 2: Short Answer Questions ### Question 11 Explain the difference between direct and indirect dependencies in go.mod.
View Answer **Direct dependencies** are packages that your code explicitly imports. They appear in the require block without the `// indirect` comment. **Indirect dependencies** are packages that your direct dependencies need, but your code doesn't import directly. They're marked with `// indirect` in go.mod. Example: ```go require ( github.com/hashicorp/terraform-plugin-framework v1.5.0 // direct github.com/fatih/color v1.16.0 // indirect ) ```
--- ### Question 12 Why should the go.sum file be committed to version control?
View Answer go.sum should be committed because: 1. **Reproducible builds**: Ensures everyone gets the exact same dependencies 2. **Security**: Detects tampering or corruption of dependencies 3. **Integrity**: Verifies downloaded modules match expected checksums 4. **Team consistency**: All developers use identical dependency versions Without go.sum, builds might use different dependency versions, causing inconsistencies.
--- ### Question 13 What is the purpose of the Provider Address in main.go, and what format should it follow?
View Answer The **Provider Address** identifies where the provider is published in the Terraform Registry. **Format:** ``` registry.terraform.io/{namespace}/{provider-name} ``` **Example:** ```go Address: "registry.terraform.io/YOUR_USERNAME/mycloud" ``` **Purpose:** - Uniquely identifies the provider - Enables Terraform to locate and download it - Required for registry publication - Used in `required_providers` blocks
--- ### Question 14 Explain Minimum Version Selection (MVS) in Go modules.
View Answer **Minimum Version Selection (MVS)** is Go's dependency resolution algorithm. **How it works:** - Selects the **minimum** version that satisfies all requirements - Does NOT automatically update to latest versions - Ensures predictability and stability **Example:** ``` Your code requires: v1.2.0 Dependency A requires: v1.1.0 Dependency B requires: v1.3.0 Go selects: v1.3.0 ``` v1.3.0 is the minimum version that satisfies all requirements (≥ v1.1.0, ≥ v1.2.0, and ≥ v1.3.0). **Benefits:** - Reproducible builds - No surprise updates - Explicit version management
--- ### Question 15 What is the difference between `pkg/` and `internal/` directories in Go projects?
View Answer **internal/:** - **Private packages** that cannot be imported by external modules - Go enforces this at the compiler level - Used for provider implementation code - Recommended for Terraform providers **pkg/:** - **Public packages** that can be imported by other projects - No compiler restrictions - Used for shared libraries and utilities **For providers:** Use `internal/` because provider code shouldn't be imported as a library—providers are consumed via Terraform's plugin protocol, not Go imports.
--- ## Part 3: Hands-On Exercises ### Exercise 1: Dependency Investigation Using the provider you created in the lab: ```bash # List all dependencies go list -m all # Find why a specific dependency is included go mod why github.com/hashicorp/terraform-plugin-go # View dependency graph go mod graph | head -20 ``` **Task:** Explain the dependency chain from your provider to `terraform-plugin-go`.
View Answer The dependency chain typically looks like: ``` your-provider └─> terraform-plugin-framework └─> terraform-plugin-go ``` **Explanation:** - Your provider directly depends on Plugin Framework - Plugin Framework depends on Plugin Go for low-level GRPC communication - This makes Plugin Go an indirect dependency in your provider You can verify with: ```bash go mod why github.com/hashicorp/terraform-plugin-go ```
--- ### Exercise 2: Project Structure Verification Create a script to verify your provider follows standard structure.
View Answer ```bash #!/bin/bash echo "Checking provider structure..." # Required files required_files=( "main.go" "go.mod" "go.sum" "README.md" "LICENSE" ".gitignore" ) # Required directories required_dirs=( "internal/provider" "examples/provider" "docs" ) echo "" echo "Required Files:" for file in "${required_files[@]}"; do if [ -f "$file" ]; then echo "✅ $file" else echo "❌ $file (missing)" fi done echo "" echo "Required Directories:" for dir in "${required_dirs[@]}"; do if [ -d "$dir" ]; then echo "✅ $dir" else echo "❌ $dir (missing)" fi done echo "" echo "Provider binary:" if [ -f "terraform-provider-"* ]; then echo "✅ Found provider binary" else echo "⚠️ No provider binary (run 'go build')" fi ``` Save as `check-structure.sh`, make executable, and run: ```bash chmod +x check-structure.sh ./check-structure.sh ```
--- ### Exercise 3: Version Update Challenge Update your provider's Plugin Framework dependency to a specific version. **Task:** 1. Update to terraform-plugin-framework v1.4.0 2. Verify the update 3. Test that the provider still compiles 4. Revert to v1.5.0
View Answer ```bash # 1. Update to v1.4.0 go get github.com/hashicorp/terraform-plugin-framework@v1.4.0 go mod tidy # 2. Verify grep terraform-plugin-framework go.mod # Should show: github.com/hashicorp/terraform-plugin-framework v1.4.0 # 3. Test compilation go build -o terraform-provider-test # Should succeed (no compilation errors) # 4. Revert to v1.5.0 go get github.com/hashicorp/terraform-plugin-framework@v1.5.0 go mod tidy # Verify revert grep terraform-plugin-framework go.mod # Should show: github.com/hashicorp/terraform-plugin-framework v1.5.0 ``` **Note:** Some features in v1.5.0 may not be available in v1.4.0, so your code might need adjustments for the downgrade to work.
--- ## Part 4: Troubleshooting Scenarios ### Scenario 1 You run `terraform init` and get: ``` Error: Failed to query available provider packages │ │ Could not retrieve the list of available versions for provider YOUR_USERNAME/mycloud ``` **Question:** What are three possible causes and their solutions?
View Answer **Cause 1: Provider not installed locally** - **Solution:** Verify installation path matches your OS/architecture ```bash ls ~/.terraform.d/plugins/registry.terraform.io/YOUR_USERNAME/mycloud/ ``` **Cause 2: Username mismatch** - **Solution:** Ensure username in `main.go`, Terraform config, and installation path all match **Cause 3: Wrong version specified** - **Solution:** Check version in `required_providers` matches installation path ```hcl time = { source = "registry.terraform.io/YOUR_USERNAME/mycloud" version = "0.1.0" # Must match installation path } ```
--- ### Scenario 2 After adding a new dependency, you get: ``` go: github.com/new/package@v1.0.0: verifying module: checksum mismatch ``` **Question:** How do you resolve this?
View Answer **Steps to resolve:** 1. **Clear module cache:** ```bash go clean -modcache ``` 2. **Re-download dependencies:** ```bash go mod download ``` 3. **Tidy up:** ```bash go mod tidy ``` 4. **Verify integrity:** ```bash go mod verify ``` **If issue persists:** - Check if you're behind a proxy - Verify GOPROXY settings - Ensure go.sum wasn't manually edited - Try using direct mode: `GOPROXY=direct go mod download`
--- ### Scenario 3 Your provider builds successfully but crashes when Terraform runs it with: ``` Error: Plugin did not respond ``` **Question:** What are potential causes and debugging steps?
View Answer **Potential Causes:** 1. **Wrong provider address** in main.go vs Terraform config 2. **Incomplete provider implementation** 3. **Panic in provider code** 4. **Architecture mismatch** (ARM vs AMD64) **Debugging Steps:** 1. **Enable debug logging:** ```bash TF_LOG=DEBUG terraform plan ``` 2. **Run provider directly:** ```bash ./terraform-provider-mycloud ``` Should show usage message, not crash 3. **Check provider address:** ```go // In main.go Address: "registry.terraform.io/YOUR_USERNAME/mycloud" ``` ```hcl # In main.tf required_providers source = "registry.terraform.io/YOUR_USERNAME/mycloud" ``` Must match exactly! 4. **Verify architecture:** ```bash file terraform-provider-mycloud # Should match your system architecture ``` 5. **Check for panics:** Add recover handlers or run with debugger: ```bash ./terraform-provider-mycloud -debug ```
--- ## Part 5: Advanced Challenges ### Challenge 1: Multi-Platform Build Create a script that builds your provider for multiple platforms.
View Answer ```bash #!/bin/bash # build-multi.sh - Build provider for multiple platforms PROVIDER_NAME="mycloud" VERSION="0.1.0" platforms=( "darwin/amd64" "darwin/arm64" "linux/amd64" "linux/arm64" "windows/amd64" ) for platform in "${platforms[@]}"; do IFS='/' read -r GOOS GOARCH <<< "$platform" output="dist/terraform-provider-${PROVIDER_NAME}_v${VERSION}_${GOOS}_${GOARCH}" if [ "$GOOS" = "windows" ]; then output="${output}.exe" fi echo "Building for $GOOS/$GOARCH..." GOOS=$GOOS GOARCH=$GOARCH go build -o "$output" \ -ldflags="-X main.version=${VERSION}" if [ $? -eq 0 ]; then echo "✅ Built: $output" else echo "❌ Failed: $GOOS/$GOARCH" fi done echo "" echo "Build complete! Binaries in dist/" ls -lh dist/ ``` **Usage:** ```bash chmod +x build-multi.sh ./build-multi.sh ```
--- ### Challenge 2: CI/CD Workflow Design a GitHub Actions workflow for testing and building your provider.
View Answer Create `.github/workflows/test.yml`: ```yaml name: Tests on: pull_request: paths-ignore: - 'README.md' push: branches: - main permissions: contents: read jobs: test: name: Test runs-on: ubuntu-latest timeout-minutes: 15 strategy: fail-fast: false matrix: go-version: ['1.21', '1.22'] terraform-version: ['1.5', '1.6', '1.7'] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: $ - uses: hashicorp/setup-terraform@v3 with: terraform_version: $ terraform_wrapper: false - name: Go mod download run: go mod download - name: Go mod verify run: go mod verify - name: Go vet run: go vet ./... - name: Go build run: go build -v ./... - name: Go test run: go test -v -cover -timeout=120s ./... ``` This workflow: - Tests multiple Go versions (1.21, 1.22) - Tests multiple Terraform versions (1.5, 1.6, 1.7) - Runs on PRs and main branch pushes - Verifies dependencies - Runs all tests with coverage
--- ## Summary **Module 3: Development Setup** covered: - ✅ Go installation and configuration - ✅ Project scaffolding methods - ✅ Standard project structure - ✅ Dependency management with Go modules - ✅ Hands-on provider development - ✅ Local testing and verification **Next Steps:** - Review any questions you missed - Revisit corresponding chapters for weak areas - Complete all hands-on exercises - Move on to Module 4 when ready [Continue to Module 4: Provider Basics →](/hashicorp/terraform-provider-development/provider-basics/){: .btn .btn--primary} --- **Previous:** [← Hands-On Lab](/hashicorp/terraform-provider-development/hands-on-lab/) *Last updated: June 30, 2026*

Updated: