Help us understand the problem. What is going on with this article?

[JAWS-UG CLI]Amazon AppStream 2.0 入門 (1) VPC環境の作成

More than 3 years have passed since last update.

この記事について

JAWS-UG CLI専門支部 #76 AppStream 2.0入門で実施するハンズオン用の手順書です。

前提条件

必要な権限

作業にあたっては、以下の権限を有したIAMユーザもしくはIAMロールを利用してください。

  • AppStream(2.0)のフルコントロール権限
  • EC2のフルコントロール権限
  • CloudFormationの関するフルコントロール権限
  • IAMの関するフルコントロール権限

0. 準備

0.1. リージョンを指定

コマンド
export AWS_DEFAULT_REGION="ap-northeast-1"

0.2. 資格情報を確認

コマンド
aws configure list

インスタンスプロファイルを設定したEC2インスタンスでアクセスキーを設定せずに実行した場合、以下のようになります。

結果
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************QSAA         iam-role
secret_key     ****************c1xY         iam-role
    region                us-west-2              env    AWS_DEFAULT_REGION

0.3. バージョン確認

コマンド
aws --version
結果
aws-cli/1.11.35 Python/2.7.12 Linux/4.4.35-33.55.amzn1.x86_64 botocore/1.4.92

0.4. バージョンアップ(必要に応じて)

コマンド
sudo pip install -U awscli

1. VPC環境の構築

AppStream 2.0の環境(Fleet、詳細は後述)はVPC上のPrivate Subnet上に構築します。
クライアント環境がインターネットアクセスを必要とする場合、併せてNAT Gateway(もしくはNAT Instance)も必要となります。
(Public SubnetにFleetを構築してもPublic IPやEIPはアタッチされません。)

Network Settings for Fleet Instances

今回は、CloudFormationでVPC環境を一括で構築します。

VPC関連の構成は、以下の資料をご確認ください。

JAWS-UG CLI専門支部 #76 Amazon AppStream 2.0 入門

1.1. CloudFormation テンプレートの生成

コマンド
CF_TEMPLATE_FILE_NAME="VPC4AppAstream20.yml"
コマンド
cat << EOF > ${CF_TEMPLATE_FILE_NAME}
AWSTemplateFormatVersion: "2010-09-09"
Description: JAWS-UG CLI AppStream 2.0 Hands-on
Resources:
    VPC4Appstream:
        Type: AWS::EC2::VPC
        Properties:
            CidrBlock: "10.0.0.0/16"
    IGW4Appstream:
        Type: AWS::EC2::InternetGateway
    AttachIGW:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
            VpcId:
                Ref: VPC4Appstream
            InternetGatewayId:
                Ref: IGW4Appstream
    PublicSubnetA4Appstream:
        Type: AWS::EC2::Subnet
        Properties: 
            AvailabilityZone: 
                Fn::Select: 
                    - 0
                    - Fn::GetAZs: ""
            CidrBlock: "10.0.0.0/24"
            MapPublicIpOnLaunch: true
            VpcId: 
                Ref: VPC4Appstream
    PublicSubnetC4Appstream:
        Type: AWS::EC2::Subnet
        Properties: 
            AvailabilityZone: 
                Fn::Select: 
                    - 1
                    - Fn::GetAZs: ""
            CidrBlock: "10.0.1.0/24"
            MapPublicIpOnLaunch: true
            VpcId: 
                Ref: VPC4Appstream
    PrivateSubnetA4Appstream:
        Type: AWS::EC2::Subnet
        Properties: 
            AvailabilityZone: 
                Fn::Select: 
                    - 0
                    - Fn::GetAZs: ""
            CidrBlock: "10.0.128.0/24"
            VpcId: 
                Ref: VPC4Appstream
    PrivateSubnetC4Appstream:
        Type: AWS::EC2::Subnet
        Properties: 
            AvailabilityZone: 
                Fn::Select: 
                    - 1
                    - Fn::GetAZs: ""
            CidrBlock: "10.0.129.0/24"
            VpcId: 
                Ref: VPC4Appstream
    EIP4NAT:
        Type: AWS::EC2::EIP
        Properties:
            Domain: vpc
    NATGW4AppStream:
        Type: AWS::EC2::NatGateway
        Properties:
            AllocationId:
                Fn::GetAtt:
                    - EIP4NAT
                    - AllocationId
            SubnetId:
                Ref: PublicSubnetA4Appstream
    PublicRT4AppStream:
        Type: AWS::EC2::RouteTable
        Properties:
            VpcId:
                Ref: VPC4Appstream
    PrivateRT4AppStream:
        Type: AWS::EC2::RouteTable
        Properties:
            VpcId:
                Ref: VPC4Appstream
    PublicDefaultRoute:
        Type: AWS::EC2::Route
        Properties: 
            DestinationCidrBlock: "0.0.0.0/0"
            GatewayId: 
                Ref: IGW4Appstream
            RouteTableId: 
                Ref: PublicRT4AppStream
    PrivateDefaultRoute:
        Type: AWS::EC2::Route
        DependsOn: NATGW4AppStream
        Properties: 
            DestinationCidrBlock: "0.0.0.0/0"
            NatGatewayId: 
                Ref: NATGW4AppStream
            RouteTableId: 
                Ref: PrivateRT4AppStream
    PublicSubnetARouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            SubnetId:
                Ref: PublicSubnetA4Appstream
            RouteTableId:
                Ref: PublicRT4AppStream
    PublicSubnetCRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            SubnetId:
                Ref: PublicSubnetC4Appstream
            RouteTableId:
                Ref: PublicRT4AppStream
    PrivateSubnetARouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            SubnetId:
                Ref: PrivateSubnetA4Appstream
            RouteTableId:
                Ref: PrivateRT4AppStream
    PrivateSubnetCRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            SubnetId:
                Ref: PrivateSubnetC4Appstream
            RouteTableId:
                Ref: PrivateRT4AppStream
Outputs: 
    PrivateSubnetID1: 
        Value: !Ref PrivateSubnetA4Appstream
    PrivateSubnetID2: 
        Value: !Ref PrivateSubnetC4Appstream
    IPv4Address4Nat: 
        Value: !Ref EIP4NAT
EOF

cat ${CF_TEMPLATE_FILE_NAME}

1.2. CloudFormation テンプレートの検証

※ macOS Sierraで前述のヒアドキュメントを実行すると、検証に失敗する場合があるようです。変数展開は行っていないので、検証に失敗した場合はエディタに直接コピペしてみてください。

コマンド
aws cloudformation validate-template \
    --template-body file://${CF_TEMPLATE_FILE_NAME}
結果
{
    "Description": "JAWS-UG CLI AppStream 2.0 Hands-on",
    "Parameters": []
}

1.3. CloudFormation Stackの作成

CloudFormation Stack名の指定

コマンド
CF_STACK_NAME="VPC4AppStream20"

同名のCloudFormation Stackがないことを確認

コマンド
aws cloudformation describe-stacks \
    --query Stacks[?StackName==\'${CF_STACK_NAME}\']
結果
[]

CloudFormation Stackの作成

コマンド
aws cloudformation create-stack \
    --stack-name ${CF_STACK_NAME} \
    --template-body file://${CF_TEMPLATE_FILE_NAME}
結果
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:788063364413:stack/VPC4AppStream20/6331d230-cf33-11e6-8944-500c44f24c82"
}

CloudFormation Stackの作成完了を待機

3分程度で作成が完了すると思います。

コマンド
aws cloudformation wait stack-create-complete \
    --stack-name ${CF_STACK_NAME}
結果
(返値無し)

1.4. 作成したCloudFormation Stackの確認

コマンド
aws cloudformation describe-stacks \
    --stack-name ${CF_STACK_NAME}
結果
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:788063364413:stack                                                                                                                                                            /VPC4AppStream20/6331d230-cf33-11e6-8944-500c44f24c82",
            "Description": "JAWS-UG CLI AppStream 2.0 Hands-on",
            "Tags": [],
            "Outputs": [
                {
                    "OutputKey": "PrivateSubnetID2",
                    "OutputValue": "subnet-61ef4139"
                },
                {
                    "OutputKey": "PrivateSubnetID1",
                    "OutputValue": "subnet-55731523"
                },
                {
                    "OutputKey": "IPv4Address4Nat",
                    "OutputValue": "52.199.195.74"
                }
            ],
            "CreationTime": "2016-12-31T08:30:29.604Z",
            "StackName": "VPC4AppStream20",
            "NotificationARNs": [],
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false
        }
    ]
}

1.5. パラメータの確認

以降の手順で必要になるパラメータを抽出します。

コマンド
OUTPUTKEY_SUBNETID1="PrivateSubnetID1"
OUTPUTKEY_SUBNETID2="PrivateSubnetID2"
OUTPUTKEY_IPV4ADDRESS4NAT="IPv4Address4Nat"
コマンド
SUBNETID1=$(aws cloudformation describe-stacks \
    --stack-name ${CF_STACK_NAME} \
    --query Stacks[].Outputs[?OutputKey==\`${OUTPUTKEY_SUBNETID1}\`].OutputValue[] \
    --output text) \
    && echo ${SUBNETID1}
結果
subnet-********
コマンド
SUBNETID2=$(aws cloudformation describe-stacks \
    --stack-name ${CF_STACK_NAME} \
    --query Stacks[].Outputs[?OutputKey==\`${OUTPUTKEY_SUBNETID2}\`].OutputValue[] \
    --output text) \
    && echo ${SUBNETID2}
結果
subnet-********
コマンド
IPV4ADDRESS4NAT=$(aws cloudformation describe-stacks \
    --stack-name ${CF_STACK_NAME} \
    --query Stacks[].Outputs[?OutputKey==\`${OUTPUTKEY_IPV4ADDRESS4NAT}\`].OutputValue[] \
    --output text) \
    && echo ${IPV4ADDRESS4NAT}
結果
**.**.**.**

以上

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away