This tutorial will guide you through the process of installing GnuPG (GPG), generating a secure key, and using it to encrypt and decrypt a terraform state file. All this can be done on a macOS system.

Installing GPG

Let’s start with installing GPG. You can use the homebrew package manager, which simplifies the process.

brew install gpg

Generating a Key

Once you’ve installed GPG, it’s time to generate a secure key.

gpg --expert --full-generate-key

You’ll see a prompt asking for the kind of key you want. Choose ECC (sign and encrypt).

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection? 9

When asked to choose the type of elliptic curve, go for (1) Curve 25519. This provides robust security.

Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (2) Curve 448
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1

As for the expiry of the key, it’s common to set this to 1y (1 year). Alternatively, you can set it to never for the key to never expire. Be aware that using a key for too long without changing it can pose a security risk. It’s best to set a reminder to change your key every year.

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y

Next, you’ll confirm your selections and provide a user ID for the key. This usually includes your name, email, and an optional comment.

GnuPG needs to construct a user ID to identify your key.

Real name: a-user
Email address: a-user@a-domain.local
Comment: 
You selected this USER-ID:
    "a-user <a-user@a-domain.local>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? 

Lastly, you’ll enter a passphrase. This is an added layer of security for your private key. Ensure to choose a strong passphrase that you can remember.

After following these steps, your key gets stored in your GPG keyring. You can view your keys using gpg --list-secret-keys. The generated key is both your private and public key pair. You can export your public key and share it with others who might want to verify your signatures or encrypt messages for you.

Please note that your private key must always remain secure and never be shared.

Encrypting and Decrypting Your State File

With the GPG set up complete, let’s move on to encrypting and decrypting your state file. This step is essential for adding the encrypted version of the file to GitHub, you should also ensure that your repo remains private and the un-encrypted state file is never committed. I have written a little script to help with this.

And then to use this:

./crypt_state.sh -encrypt a-user@a-domain.local
./crypt_state.sh -decrypt a-user@a-domain.local