如何使用 java 在 EC-2 实例上执行 shell 脚本?

How to execute a shell script on EC-2 instance using java?

我需要编写一个 java 程序来在孟买地区创建一个 AWS EC2 实例。 该程序还应该能够在实例处于就绪状态后在 EC2 实例上执行 shell 脚本。我不想在我的程序中硬编码脚本。该程序应读取外部脚本文件。我无法找到一份文档来说明如何做。

这是我想出的:

public class CreateInstance
{
    private static final AWSCredentials AWS_CREDENTIALS;

    static {
        // Your accesskey and secretkey
        AWS_CREDENTIALS = new BasicAWSCredentials(
                "My ID",
                "My secret"
        );
    }

    public static Integer getInstanceStatus(String instanceId, AmazonEC2 ec2) {
        DescribeInstancesRequest describeInstanceRequest = new DescribeInstancesRequest().withInstanceIds(instanceId);
        DescribeInstancesResult describeInstanceResult = ec2.describeInstances(describeInstanceRequest);
        InstanceState state = describeInstanceResult.getReservations().get(0).getInstances().get(0).getState();
        return state.getCode();
    }
    public static void main(String[] args) {

        // Set up the amazon ec2 client
        AmazonEC2 ec2Client = AmazonEC2ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(AWS_CREDENTIALS))
                .withRegion(Regions.AP_SOUTH_1)
                .build();

        // Launch an Amazon EC2 Instance
        RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-009110a2bf8d7dd0a")
                .withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
                .withMinCount(1)
                .withMaxCount(1)
                .withKeyName("prakhar")
                .withNetworkInterfaces(new InstanceNetworkInterfaceSpecification()
                        .withAssociatePublicIpAddress(true)
                        .withDeviceIndex(0));

        RunInstancesResult runInstancesResult = ec2Client.runInstances(runInstancesRequest);

        Instance instance = runInstancesResult.getReservation().getInstances().get(0);
        String instanceId = instance.getInstanceId(); 
        //String Id = instanceId;
        System.out.println("EC2 Instance Id: " + instanceId);

        // Setting up the tags for the instance
        CreateTagsRequest createTagsRequest = new CreateTagsRequest()
                .withResources(instance.getInstanceId())
                .withTags(new Tag("Name", "prakhardemo"));
        ec2Client.createTags(createTagsRequest);

        // Starting the Instance
        StartInstancesRequest startInstancesRequest = new StartInstancesRequest().withInstanceIds(instanceId);

        ec2Client.startInstances(startInstancesRequest);
        //wait until its in running state
        Integer instanceState = -1;
        while(instanceState != 16) { //Loop until the instance is in the "running" state.
            instanceState = getInstanceStatus(instanceId, ec2Client);
            try {
                Thread.sleep(5000);
            } catch(InterruptedException e) {}
        }
        System.out.println("your created instance is now in running state !");
    }
}

您可以使用 AWS EC2 User Data 执行此操作。

When you launch an instance in Amazon EC2, you have the option of passing user data to the instance that can be used to perform common automated configuration tasks and even run scripts after the instance starts.

按如下方式更改您的代码:

RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-009110a2bf8d7dd0a")
    .withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
    .withMinCount(1)
    .withMaxCount(1)
    .withKeyName("prakhar")
    .withUserData(getUserDataScript())
    .withNetworkInterfaces(new InstanceNetworkInterfaceSpecification()
        .withAssociatePublicIpAddress(true)
        .withDeviceIndex(0));

其中getUserDataScript()可以如下:

private static String getUserDataScript(){
    ArrayList<String> lines = new ArrayList<String>();

    # Open and Read Your File into Lines

    String str = new String(Base64.encodeBase64(join(lines, "\n").getBytes()));
    return str;
}