LoginSignup
4
4

More than 5 years have passed since last update.

AWS SDK for JavaでVPCを構築する

Last updated at Posted at 2014-01-16

AWS SDK for JavaでVPCを構築するようなサンプルがあまりなかったので書いてみました。

お題

Amazon VPCに関するドキュメントにある以下の構成でVPCを構築します。

  • VPC
    • CIDR : 10.0.0.0/16
  • Subnet
    • SubnetA(Public Subnet)
      • CIDR : 10.0.0.0/24
    • SubnetB(Private Subnet)
      • CIDR : 10.0.1.0/24
  • EC2
    • InstanceA
      • SubnetAに所属
      • EIPあり
    • InstanceB
      • SubnetBに所属
      • EIPなし

ドキュメントの方ではEC2インスタンスは各Subnetに3インスタンス建てられていますが、今回はめんどくさいので1インスタンスにしています。

※ イメージはドキュメントを御覧ください。

環境・ライブラリ

  • Java7
  • AWS SDK for Java 1.6.1
  • Guava 15.0

なおAWSのロギング制御のためにslf4j( + jcl-over-slf4j) + logback を利用していますが、
コードのほうではめんどくさかったので使っていません。

コード

でこんな感じになりました。
所感としては普通にコンソールとほぼほぼ同じ事をしていくだけです。
AWS SDK for JavaではEC2に絡むところはだいたいAmazonEC2Client経由で処理を行います。
AmazonEC2Clientには各種AWSのリソースを操作するメソッド群がいるので、それを呼び出すのですが、
細かいパラメータはメソッドと同名 + Requestというクラスを利用して設定を行います。

その2つだけ覚えておけば、後は補完使ってメソッド名を探せば大体の設定は行えるはずです。

なお一部OpsWorks関連のクラス名とEC2関連のクラス名がかぶっているところがあるので、注意しておくといいと思います。

VpcSample
package stk;

import java.util.List;

import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AllocateAddressRequest;
import com.amazonaws.services.ec2.model.AssociateAddressRequest;
import com.amazonaws.services.ec2.model.AssociateRouteTableRequest;
import com.amazonaws.services.ec2.model.AttachInternetGatewayRequest;
import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
import com.amazonaws.services.ec2.model.CreateInternetGatewayRequest;
import com.amazonaws.services.ec2.model.CreateInternetGatewayResult;
import com.amazonaws.services.ec2.model.CreateRouteRequest;
import com.amazonaws.services.ec2.model.CreateRouteTableRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
import com.amazonaws.services.ec2.model.CreateSubnetRequest;
import com.amazonaws.services.ec2.model.CreateVpcRequest;
import com.amazonaws.services.ec2.model.CreateVpcResult;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.DomainType;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.InstanceType;
import com.amazonaws.services.ec2.model.InternetGateway;
import com.amazonaws.services.ec2.model.IpPermission;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.RouteTable;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.RunInstancesResult;
import com.amazonaws.services.ec2.model.Subnet;
import com.amazonaws.services.ec2.model.Tenancy;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

public class VpcSample {

    private static final String KEY_PAIR_NAME = "oohashiKey";
    private static final String AMI_AMAZON_LINUX_64BIT = "ami-0d13700c";
    private static final String ALL_IP_RANGE = "0.0.0.0/0";

    /**
     * Amazon VPCのドキュメントと同じVPCネットワークを作成する。
     * 
     * @see <a href="http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Internet_Gateway.html#api_cli_overview">対象ドキュメント</a>
     * 
     * @param args 無し
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {

        //クライアントの作成
        AmazonEC2 ec2 = new AmazonEC2Client(new ClasspathPropertiesFileCredentialsProvider());      
        ec2.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1));
        String az = ec2.describeAvailabilityZones().getAvailabilityZones().get(0).getZoneName();

        //VPCの作成
        CreateVpcRequest cvr = new CreateVpcRequest();

        String cidrBlock = "10.0.0.0/16";
        cvr.withInstanceTenancy(Tenancy.Default)
            .withCidrBlock(cidrBlock);
        CreateVpcResult createVpcResult = ec2.createVpc(cvr);       
        String vpcId = createVpcResult.getVpc().getVpcId();

        System.out.println("VPC " + vpcId + " を作成しました");

        //サブネットの作成
        String subnetACidrBlock = "10.0.0.0/24";        
        Subnet subnetA = createSubnet(ec2, vpcId, az, subnetACidrBlock);

        String subnetBCidrBlock = "10.0.1.0/24";
        Subnet subnetB = createSubnet(ec2, vpcId, az, subnetBCidrBlock);        

        //サブネットの中に適当なEC2インスタンスを作成
        RunInstancesResult subnetAInstanceResult = runNewEC2(ec2, subnetA);
        RunInstancesResult subnetBInstanceResult = runNewEC2(ec2, subnetB);

        List<Instance> instanceList = Lists.newArrayList(subnetAInstanceResult.getReservation().getInstances());
        instanceList.addAll(subnetBInstanceResult.getReservation().getInstances());

        List<String> instanceIdList = Lists.transform(instanceList, new Function<Instance, String>() {
            public String apply(Instance input) {
                return input.getInstanceId();
            }
        });

        sleepUntilInstancesIsRunning(ec2, instanceIdList);

        //InternetGatewayの作成
        CreateInternetGatewayRequest cigr = new CreateInternetGatewayRequest();
        CreateInternetGatewayResult internetGatewayResult = ec2.createInternetGateway(cigr);        
        InternetGateway internetGateway = internetGatewayResult.getInternetGateway();

        System.out.println("ゲートウェイ " + internetGateway.getInternetGatewayId() + "を作成しました");

        //GatewayをVPCにアタッチ
        AttachInternetGatewayRequest aigr = new AttachInternetGatewayRequest();
        aigr.withInternetGatewayId(internetGateway.getInternetGatewayId())
            .withVpcId(vpcId);
        ec2.attachInternetGateway(aigr);
        System.out.printf("Attach %s to %s\n" , internetGateway.getInternetGatewayId() , vpcId);

        //カスタムルートテーブルの作成
        CreateRouteTableRequest crtr = new CreateRouteTableRequest();
        crtr.withVpcId(vpcId);

        RouteTable routeTable = ec2.createRouteTable(crtr).getRouteTable();
        System.out.printf("ルートテーブル %s を作成しました\n", routeTable.getRouteTableId());

        //ルートの作成
        CreateRouteRequest crr = new CreateRouteRequest();
        crr.withRouteTableId(routeTable.getRouteTableId())
            .withDestinationCidrBlock(ALL_IP_RANGE)
            .withGatewayId(internetGateway.getInternetGatewayId());
        ec2.createRoute(crr);

        System.out.printf("ゲートウェイ[%s]へのルーティングを作成しました\n", internetGateway.getInternetGatewayId());

        //ルートテーブルをサブネットに紐付け
        AssociateRouteTableRequest artr = new AssociateRouteTableRequest();
        artr.withRouteTableId(routeTable.getRouteTableId())
            .withSubnetId(subnetA.getSubnetId());
        ec2.associateRouteTable(artr);
        System.out.printf("ルートテーブル[%s]をサブネット[%s]に紐付けました。\n", routeTable.getRouteTableId(), subnetA.getSubnetId());

        //http/https用のSGを作成
        CreateSecurityGroupRequest csgr = new CreateSecurityGroupRequest();
        csgr.withDescription("for vpc")
            .withGroupName("VPC_SG")
            .withVpcId(vpcId);

        CreateSecurityGroupResult securityGroup = ec2.createSecurityGroup(csgr);

        IpPermission http = new IpPermission();
        http
            .withIpProtocol("tcp")
            .withFromPort(80)
            .withToPort(80)
            .withIpRanges(ALL_IP_RANGE);

        IpPermission https = new IpPermission();
        https
            .withIpProtocol("tcp")
            .withFromPort(443)
            .withToPort(443)
            .withIpRanges(ALL_IP_RANGE);


        AuthorizeSecurityGroupIngressRequest asger = new AuthorizeSecurityGroupIngressRequest();
        asger
            .withIpPermissions(Lists.newArrayList(http, https))
            .withGroupId(securityGroup.getGroupId());

        ec2.authorizeSecurityGroupIngress(asger);

        System.out.printf("SG[%s]を作成しました\n", securityGroup.getGroupId());

        //EIPの作成
        AllocateAddressRequest aar = new AllocateAddressRequest();
        aar.withDomain(DomainType.Vpc);     
        String ip = ec2.allocateAddress(aar).getPublicIp();
        System.out.printf("EIP[%s]を取得しました\n", ip);

        //EIPの割り当て
        AssociateAddressRequest associateRequest = new AssociateAddressRequest();
        associateRequest.withPublicIp(ip).withInstanceId(subnetAInstanceResult.getReservation().getInstances().get(0).getInstanceId());

        ec2.associateAddress(associateRequest);
        System.out.printf("EC2インスタンス[%s]にEIP[%s]を割り当てました。\n", subnetAInstanceResult.getReservation().getInstances().get(0).getInstanceId(), ip);

        System.out.println("すべての作成処理が完了しました\n");
    }

    private static void sleepUntilInstancesIsRunning(AmazonEC2 ec2,
            List<String> instanceIdList) throws InterruptedException {
        while(true) {
            DescribeInstancesResult instanceStatusResult = ec2.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceIdList));

            if(Iterables.all(instanceStatusResult.getReservations(), new Predicate<Reservation>() {
                @Override
                public boolean apply(Reservation input) {
                    return Iterables.all(input.getInstances(), new Predicate<Instance>() {
                        @Override
                        public boolean apply(Instance input) {
                            return input.getState().getName().equalsIgnoreCase(InstanceStateName.Running.toString());
                        }
                    });
                }
            })){
                break;
            } else {
                System.out.println("sleeping...");
                Thread.sleep(1000);
            }
        }
    }

    private static RunInstancesResult runNewEC2(AmazonEC2 ec2, Subnet subnet) {
        //EC2インスタンスの設定
        RunInstancesRequest request = new RunInstancesRequest()
            .withImageId(AMI_AMAZON_LINUX_64BIT) //amazon-linux 64bit
            .withMaxCount(1)
            .withMinCount(1)
            .withKeyName(KEY_PAIR_NAME)
            .withInstanceType(InstanceType.T1Micro)
            .withSubnetId(subnet.getSubnetId());

        RunInstancesResult result = ec2.runInstances(request);

        System.out.println("EC2インスタンス " + result.getReservation().getInstances().get(0).getInstanceId() + "を作成しました");

        return result;
    }

    private static Subnet createSubnet(AmazonEC2 ec2, String vpcId, String az, String subnetBCidrBlock) {
        CreateSubnetRequest csr = new CreateSubnetRequest();
        csr.withAvailabilityZone(az)
            .withCidrBlock(subnetBCidrBlock)
            .withVpcId(vpcId);

        Subnet subnet = ec2.createSubnet(csr).getSubnet();
        System.out.println("Subnet " + subnet.getSubnetId() + " を作成しました");

        return subnet;
    }

}

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4