Search code examples
oracle-cloud-infrastructureoci-java-sdkoci-go-sdk

Bare Metal Cloud - How to set authorized ssh keys for compute instances?


I have successfully provisioned Bare Metal Cloud compute instances using the following code:

public static Instance createInstance(
        ComputeClient computeClient,
        String compartmentId,
        AvailabilityDomain availabilityDomain,
        String instanceName,
        Image image,
        Shape shape,
        Subnet subnet
    ) {

    LaunchInstanceResponse response = computeClient.launchInstance(
        LaunchInstanceRequest.builder()
            .launchInstanceDetails(
                LaunchInstanceDetails.builder()
                    .availabilityDomain(availabilityDomain.getName())
                    .compartmentId(compartmentId)
                    .displayName(instanceName)
                    .imageId(image.getId())
                    .shape(shape.getShape())
                    .subnetId(subnet.getId())
                    .build())
            .build());  

    return response.getInstance();
}

However, I can't SSH into any instances I create via the code above, because there's no parameter on launchInstance to pass in the public key of my SSH keypair.

How can I tell the instance what SSH public key to allow? I know it must be possible somehow since the console UI allows me to provide the SSH public key as part of instance creation.


Solution

  • According to the launch instance API documentation, you need to pass your SSH public key via the ssh_authorized_keys field of the metadata parameter:

    Providing Cloud-Init Metadata

    You can use the following metadata key names to provide information to Cloud-Init:

    "ssh_authorized_keys" - Provide one or more public SSH keys to be included in the ~/.ssh/authorized_keys file for the default user on the instance. Use a newline character to separate multiple keys. The SSH keys must be in the format necessary for the authorized_keys file

    The code for this in the Java SDK looks like this:

    public static Instance createInstance(
            ComputeClient computeClient,
            String compartmentId,
            AvailabilityDomain availabilityDomain,
            String instanceName,
            Image image,
            Shape shape,
            Subnet subnet
        ) {
    
        String sshPublicKey = "ssh-rsa AAAAB3NzaC1y...key shortened for example...fdK/ABqxgH7sy3AWgBjfj some description";
    
        Map<String, String> metadata = new HashMap<>();
        metadata.put("ssh_authorized_keys", sshPublicKey);
    
        LaunchInstanceResponse response = computeClient.launchInstance(
            LaunchInstanceRequest.builder()
                .launchInstanceDetails(
                    LaunchInstanceDetails.builder()
                        .availabilityDomain(availabilityDomain.getName())
                        .compartmentId(compartmentId)
                        .displayName(instanceName)
                        .imageId(image.getId())
                        .metadata(metadata)
                        .shape(shape.getShape())
                        .subnetId(subnet.getId())
                        .build())
                .build());  
    
        return response.getInstance();
    }
    

    Then the instance will allow you to SSH to it using the SSH keypair for that public key.