Provide CloudInit Data from aws_kms_secrets

Hi,

my main motivation is to specify the host_keys to cloud-init so that i dont get new host keys upon every new instance i create. I want to use the “ssh_host.ed25519_private” field from cloud-init’ ssh module. Module reference - cloud-init 23.1.1 documentation

I dont want to store these keys directly in the cloud-init (and thus in my git) but have them encrypted in the repository. So: I manually created a key with ssh-keygen, stored that in a file and encrypted that file with the aws cli (which would then get into git).

    aws kms encrypt \
        --key-id arn:aws:kms:eu-central-1:XXXXKEYIDXXX  \
        --region eu-central-1 \
        --plaintext file://./hostkey \
        --output text \
        --query CiphertextBlob > hostkey.encrypted

To get that value into cloud-inits template i have used the Fn.templatefile function.

host_key = DataAwsKmsSecretsSecret(
            name="hostey",
            payload=Path(ROOTDIR).joinpath("hostkey.encrypted").read_text(),
            key_id="KEYID"
        )
        host_key_secret = DataAwsKmsSecrets(self, "kms", secret=[host_key])
        cloudconfig = Fn.templatefile(
            Path(ROOTDIR).joinpath("assets/cloudconfig.yml.tftpl").as_posix(),
            dict({
                "ssh_host_key": Fn.yamlencode(host_key_secret.plaintext.lookup("hostey")),
                "ssh_host_key_pub": "ssh-ed25519 AAAAXXX"
            })
        )

The cloud-init template file looks like this:

ssh_keys:
  ssh_genkeytypes: []  
  ed25519_private: |
    ${ssh_host_key}
  ed25519_public: |
    ${ssh_host_key_pub}

My problem is: That the key value is not properly read from cloud-init. The error i see on the machines cloud-init.logs is

2023-03-12 10:26:01,325 - util.py[WARNING]: Failed loading yaml blob. Invalid format at line 33 column 3: "while scanning a simple key
  in "<unicode string>", line 33, column 3:
      -----BEGIN OPENSSH PRIVATE KEY-----
      ^
could not find expected ':'
  in "<unicode string>", line 34, column 3:
      b3BlbnNzaC1rZXktdjEAAAAABG5vbmUA ... 
      ^"

So, it seems that the value is correctly retrieved but i need to do something else with the value then Fn.yamlencode() so that cloud-init does not choke upon trying to read it. But what?

Also: If anybody has a simpler way of providing the host key, i am all ears. :slight_smile:

Thank you
Manuel

Iwanted to just write the key files directly with the write_files directive from cloud-init. I have base64encoded the key value and then used encoding: b64. on the write_files.

cdktf:

Fn.base64encode(host_key_secret.plaintext.lookup("hostey"))

template:

  - content: ${host_key}
    path: /etc/ssh/ssh_host_ed25519_key
    encoding: b64
    owner: "root:root"
    permissions: "0600"

Unfortunatly, my ssh then just refuses to start. Unfortunatly, I dont have any remote logging in place so i cant see anything it might complain about.

After a while i eventually got the “write the key to a keyfile” solution working… I have configure ssh in cloud-config so that it does not generate any keys (because i thought i dont need them anyhow) because i only want to have one “HostKey” in sshd_config. But that somehow leads to sshd not starting.

Anyway, now its working. Not with the cloud-init way but with a more manual approach … well, i’ll take that. :slight_smile: