Reading Go Before Writing It
Before diving into concurrency and deployment, you need to be able to read and write basic Go. This section covers the minimum syntax required to understand every example in this lesson.
Packages and Imports
Every Go file belongs to a package. The main package is special — it defines an executable program. The main() function inside it is the entry point.
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("Hello, Ops world")
}
fmt is the standard formatting package. os gives you access to the operating system (files, environment variables, exit codes). You import only what you use — Go refuses to compile if you import a package and never use it. This enforces clean code at the compiler level.
Variables and Types
Go is statically typed, meaning every variable has a type known at compile time. The := operator declares and assigns in one step, with the type inferred from the right-hand side.
// Explicit type declaration
var hostname string = "web01"
// Short declaration — type inferred as string
region := "us-east-1"
// Multiple assignment
port, protocol := 8080, "tcp"
fmt.Printf("Connecting to %s:%d via %s\n", hostname, port, protocol)
Functions
Functions in Go can return multiple values. This is the foundation of Go's error handling pattern (covered later).
// Returns a string and an error
func getEnvOrDefault(key, defaultVal string) (string, error) {
val := os.Getenv(key)
if val == "" {
return defaultVal, nil
}
return val, nil
}
Slices and Maps
Slices are Go's dynamic arrays. Maps are key-value stores. Both are essential for Ops work.
// Slice of server hostnames
servers := []string{"web01", "web02", "db01"}
// Iterate over a slice
for i, server := range servers {
fmt.Printf("%d: %s\n", i, server)
}
// Map of environment variables
config := map[string]string{
"ENV": "production",
"REGION": "us-east-1",
}
// Access a map value safely — ok is false if key doesn't exist
region, ok := config["REGION"]
if ok {
fmt.Println("Region:", region)
}
Structs
A struct groups related fields together into a named type. Think of it as a lightweight class with no inheritance.
type Server struct {
Hostname string
IP string
Port int
Active bool
}
s := Server{
Hostname: "web01",
IP: "10.0.0.1",
Port: 443,
Active: true,
}
fmt.Printf("%s is at %s:%d\n", s.Hostname, s.IP, s.Port)
These primitives — packages, variables, functions, slices, maps, structs — are the vocabulary for everything that follows.