Skip to content

m99coder/opentofu-first-steps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenTofu: First Steps

⚠️ Disclaimer

This repository is for learning and educational purposes only.

It contains Terraform/OpenTofu scripts that create real resources, which may incur costs.

Important Notes

  • Do not use this code in production environments.
  • The resources are not configured for production security, reliability, or compliance.
  • There is no warranty or guarantee of correctness, safety, or cost containment.
  • Always review and understand the code before running it.

By using this repository, you acknowledge that you are responsible for any costs or impacts resulting from its execution.

Install

→ brew install opentofu

It’s adviced to also install the OpenTofu plugin if you are using VSCode.

Init

→ vim main.tf
→ tofu init

Don’t forget to add the relevant files to your .gitignore file, as described here.

→ tofu providers

Providers required by configuration:
.
└── provider[registry.opentofu.org/hashicorp/aws] ~> 6.0

AWS

Get the latest ARM-based Amazon Linux 2023 AMI version using the AWS CLI like this:

→ aws ec2 describe-images \
    --owners amazon \
    --filters "Name=name,Values=al2023-*-arm64" "Name=state,Values=available" \
    --query 'Images | sort_by(@, &CreationDate)[-1]' \
    --output table

Get a matching instance type eligible for the free tier using the AWS CLI like this:

→ aws ec2 describe-instance-types \
    --filters "Name=processor-info.supported-architecture,Values=arm64" \
              "Name=free-tier-eligible,Values=true" \
    --query 'InstanceTypes[*].InstanceType' \
    --output table

Now we can plan and apply the plan and check the state afterwards:

→ cat > my.tfvars <<EOF
name_prefix = "opentofu-first-steps"
ssh_key     = "~/.ssh/id_ed25519.pub"
EOF

→ tofu plan -var-file my.tfvars
→ tofu apply -var-file my.tfvars

→ tofu state list
→ tofu state show aws_instance.example

With the outputs.tf in place, we can run tofu refresh and see the output of the instance ARN.

In case you want to recreate the instance, you can use tofu taint as follows:

→ tofu taint aws_instance.example
→ tofu apply -var-file my.tfvars [-auto-approve]

Hint: SSH into the EC2 instance and check /var/log/cloud-init-output.log to see if there was any error during the setup.

Finally, clean up.

→ tofu destroy -var-file my.tfvars [-auto-approve]

Azure

→ tofu init
→ tofu providers

Providers required by configuration:
.
├── provider[registry.opentofu.org/hashicorp/azurerm] ~> 4.0
├── provider[registry.opentofu.org/hashicorp/aws] ~> 6.0
└── module.aws_instance
    └── provider[registry.opentofu.org/hashicorp/aws]
→ az login --use-device-code
→ az account show --query id --output tsv
→ cat >> my.tfvars <<EOF
subscription_id = "$(az account show --query id --output tsv)"
EOF

→ az account list | jq
→ az account list-locations | jq -r '. | sort_by(.name) | .[].name'
→ az account list-locations | jq -r '.[] | select(.name=="westeurope")'

→ az vm image list-offers --location westeurope \
    --publisher Canonical --output table
→ az vm image list-skus --location westeurope \
    --publisher Canonical --offer ubuntu-24_04-lts --output table
→ az vm image list --location westeurope \
    --publisher Canonical --offer ubuntu-24_04-lts --sku server \
    --all --output table

Have a look at https://az-vm-image.info/

→ tofu plan -target=module.azure_vm -var-file my.tfvars
→ tofu apply -target=module.azure_vm -var-file my.tfvars

Finally, clean up.

→ tofu destroy -target=module.azure_vm -var-file my.tfvars [-auto-approve]

GCP

→ tofu init
→ tofu providers

Providers required by configuration:
.
├── provider[registry.opentofu.org/hashicorp/azurerm] ~> 4.0
├── provider[registry.opentofu.org/hashicorp/google] ~> 6.0
├── provider[registry.opentofu.org/hashicorp/aws] ~> 6.0
├── module.aws_instance
│   └── provider[registry.opentofu.org/hashicorp/aws]
├── module.azure_vm
│   └── provider[registry.opentofu.org/hashicorp/azurerm]
└── module.google_vm
    └── provider[registry.opentofu.org/hashicorp/google]
→ gcloud auth login
→ gcloud auth list

→ # create project
→ gcloud projects create opentofu-first-steps
→ gcloud projects list
→ gcloud config set project opentofu-first-steps
→ gcloud config list

→ # create service account and key pair
→ gcloud iam service-accounts create opentofu-first-steps-vm-sa \
    --description="Service account for VM access" \
    --display-name="opentofu-first-steps-service-account"
→ gcloud iam service-accounts list

→ gcloud iam service-accounts keys list \
    --iam-account opentofu-first-steps-vm-sa@opentofu-first-steps.iam.gserviceaccount.com

→ # this creates and downloads a key pair as `key.json`
→ gcloud iam service-accounts keys create key.json \
    --iam-account opentofu-first-steps-vm-sa@opentofu-first-steps.iam.gserviceaccount.com

→ # grant least-privilege access to service account
→ gcloud projects add-iam-policy-binding opentofu-first-steps \
    --member="serviceAccount:opentofu-first-steps-vm-sa@opentofu-first-steps.iam.gserviceaccount.com" \
    --role="roles/compute.instanceAdmin.v1"
→ gcloud projects add-iam-policy-binding opentofu-first-steps \
    --member="serviceAccount:opentofu-first-steps-vm-sa@opentofu-first-steps.iam.gserviceaccount.com" \
    --role="roles/compute.networkAdmin"
→ gcloud projects add-iam-policy-binding opentofu-first-steps \
    --member="serviceAccount:opentofu-first-steps-vm-sa@opentofu-first-steps.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountUser"

→ cat >> my.tfvars <<EOF
project_id = "opentofu-first-steps"
EOF

Enable Compute API

# link billing account to project in order to be able to enable Compute API
→ gcloud billing accounts list
→ gcloud billing projects link opentofu-first-steps --billing-account <BILLING-ACCOUNT-ID>
→ gcloud billing projects describe opentofu-first-steps

→ # enable Compute API
→ gcloud services enable compute.googleapis.com --project opentofu-first-steps
→ gcloud services list --enabled --project opentofu-first-steps

Retrieve available regions and machine types

# get regions
→ gcloud compute regions list --format="value(name)"# get machine types matching `micro` in all zones of region `us-central1`for z in $(gcloud compute zones list --filter="region:(us-central1)" --format="value(name)"); do
    echo "Zone: $z"
    gcloud compute machine-types list --zones=$z --format="value(name)" --filter="name~'micro'"
  done

We will use e2-micro in us-central1 as this is the free-tier eligible combination.

Plan, apply, and destroy

→ tofu plan -target=module.google_vm -var-file my.tfvars
→ tofu apply -target=module.google_vm -var-file my.tfvars

Finally, clean up.

→ tofu destroy -target=module.google_vm -var-file my.tfvars [-auto-approve]

About

OpenTofu: First Steps

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages