How can I get terraforms extern to execute `ssh-keygen -y -f ~/.ssh/id_rsa`?
So what happens in first case is, as Dan's already said, there's no shell used and as such nothing to expand the ~. Quoting the documentation about program:


  Terraform does not execute the program through a shell


On the second case, bash receive in stdin something like this:

{ "-c": "ssh-keygen -y -f ~/.ssh/id_rsa" }


And this looks like a command block for bash, but -c is not a valid command.

What could work could be this kind of program (assuming no specific input):

jq -n --arg pubkey "$(ssh-keygen -y -f ~/.ssh/id_rsa)" '{"pubkey":$pubkey}'


So something like this should work to get the key in local_key["pubkey"] if I understand the documentation properly:

data "external" "local_key" {
  program = [
    "bash", "-c jq -n --arg pubkey \"$(ssh-keygen -y -f ~/.ssh/id_rsa)\" '{\"pubkey\":$pubkey}'"
  ]
}


There's a need to use bash for a one liner to take advantage of command subsitution. You can also do a .sh script like:

#!/bin/sh
jq -n --arg pubkey "$(ssh-keygen -y -f ~/.ssh/id_rsa)" '{\"pubkey\":$pubkey}'


And call this script in the program parameter.