事前作業4. EC2インスタンスの作成¶
作業の目的 [why]¶
EC2インスタンス"handson-cli"を作成します。
完了条件/事前条件 [設計者用情報]
完了条件 [after]
主処理は、以下を満たしたときに成功したものとします。
- 完了条件1
- ステータスが"running"のEC2インスタンス"handson-cli"が存在する。
事前条件 [before]
主処理の実施は、以下の状態であることを前提とします。
- 事前条件1
- ステータスが"running"のEC2インスタンス"handson-cli"が存在しない。
- 事前条件2
- AMI"amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2"が存在する。
- 事前条件3
- VPC"vpc-handson-cli"が存在する。
- 事前条件4
- VPC"vpc-handson-cli"にサブネット"subnet-public0"が存在する。
- 事前条件5
- VPC"vpc-handson-cli"にセキュリティグループ"env-maint-db"が存在する。
- 事前条件6
- インスタンスプロファイル"EC2InstanceProfileEnvMaint"が存在する。
- 事前条件7
- ユーザデータ"${HOME}/tmp/conf-ec2/postgresql.bash"が存在する。
- 事前条件8
- キーペア"<キーペア名>"が存在する。
前提と異なることが判明した場合、直ちに処理を中止します。
作業対象 [what]¶
- EC2サービス
標準時間¶
8分
前提条件¶
作業権限条件 [who]¶
本作業は、以下の作業権限を有する人が行います。
作業権限条件: EC2への権限
EC2に対してフル権限があること。
作業権限条件: IAMへの権限
IAMに対して読み取り権限があること。
作業環境条件 [where]¶
本作業は、以下の作業環境で行います。
作業環境条件1: OSとバージョン
Amazon Linuxの以下のバージョンで動作確認済
コマンド:
cat /etc/issue | head -1
結果(例):
Amazon Linux AMI release 2016.09
作業環境条件2: シェルとバージョン
bashの以下のバージョンで動作確認済
コマンド:
bash --version -v | head -1
結果(例):
GNU bash, バージョン 4.2.46(1)-release (x86_64-redhat-linux-gnu)
作業環境条件3: AWS CLIのバージョン
以下のバージョンで動作確認済
- AWS CLI 1.14.18
コマンド:
aws --version
結果(例):
aws-cli/1.14.19 Python/2.7.12 Linux/4.4.11-23.53.amzn1.x86_64 botocore/1.8.23
バージョンが古い場合は最新版に更新しましょう。
コマンド:
sudo -H pip install -U awscli
開始条件¶
作業に必要なモノ・情報 [resource]¶
作業開始には、以下が全て揃っていることが必要です。
リソース1: EC2インスタンスのタグ名
- 作成するEC2インスタンスのタグ名称です。
- 今回は"handson-cli"とします。
リソース2: AMIイメージ名
- 作成するEC2インスタンスのAMIイメージ名です。
- 今回は"amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2"とします。
リソース3: VPCのタグ名
- インスタンスが利用するVPCのタグ名称です。
- 今回は"vpc-handson-cli"とします。
リソース4: サブネットのタグ名
- 作成するインスタンスが利用するサブネットのタグ名称です。
- 今回は"subnet-public0"とします。
リソース5: セキュリティグループのタグ名
- 作成するインスタンスが利用するセキュリティグループの名称です。
- 今回は"env-maint-db"とします。
リソース6: EC2インスタンスのインスタンスタイプ
- 作成するEC2インスタンスのインスタンスタイプです。
- 今回は"t2.micro"とします。
リソース7: インスタンスプロファイル名
- 作成するEC2インスタンスが利用するインスタンスプロファイル名です。
- 今回は"EC2InstanceProfileEnvMaint"とします。
リソース8: EC2インスタンスのユーザデータファイル名
- 作成するEC2インスタンスのユーザデータファイル名です。
- 今回は"${HOME}/tmp/conf-ec2/postgresql.bash"とします。
リソース9: キーペア名
- 作成するインスタンスが利用するキーペア名です。
- 今回は"<キーペア名>"とします。
タスクの実施¶
0. パラメータの指定¶
まず変数の確認をします。
変数の確認:
cat << ETX # 0.a. AWS_DEFAULT_PROFILE: <EC2のフル権限を許可されたプロファイル> AWS_DEFAULT_PROFILE="${AWS_DEFAULT_PROFILE}" # 0.b. AWS_DEFAULT_REGION: ap-northeast-1 AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" # 0.1. EC2_INSTANCE_TAG_NAME: handson-cli EC2_INSTANCE_TAG_NAME="${EC2_INSTANCE_TAG_NAME}" # 0.2. EC2_IMAGE_NAME: amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2 EC2_IMAGE_NAME="${EC2_IMAGE_NAME}" # 0.3. VPC_TAG_NAME: vpc-handson-cli VPC_TAG_NAME="${VPC_TAG_NAME}" # 0.4. VPC_SUBNET_TAG_NAME: subnet-public0 VPC_SUBNET_TAG_NAME="${VPC_SUBNET_TAG_NAME}" # 0.5. VPC_SG_NAME: env-maint-db VPC_SG_NAME="${VPC_SG_NAME}" # 0.6. EC2_INSTANCE_TYPE: t2.micro EC2_INSTANCE_TYPE="${EC2_INSTANCE_TYPE}" # 0.7. IAM_INSTANCE_PROFILE_NAME: EC2InstanceProfileEnvMaint IAM_INSTANCE_PROFILE_NAME="${IAM_INSTANCE_PROFILE_NAME}" # 0.8. FILE_INPUT: ${HOME}/tmp/conf-ec2/postgresql.bash FILE_INPUT="${FILE_INPUT}" # 0.9. EC2_KEY_PAIR_NAME: <キーペア名> EC2_KEY_PAIR_NAME="${EC2_KEY_PAIR_NAME}" ETX
下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号について作業を行います。
0.a. プロファイルの指定¶
プロファイルの一覧を確認します。
コマンド:
cat ~/.aws/credentials \ | grep '\[' \ | sed 's/\[//g' | sed 's/\]//g'
結果(例):
iamFull-prjz-mbpr13 <EC2のフル権限を許可されたプロファイル>
変数の設定:
export AWS_DEFAULT_PROFILE='<EC2のフル権限を許可されたプロファイル>'
0.2. AMIイメージ名¶
作成するEC2インスタンスのAMIイメージ名を指定します。
変数の設定:
EC2_IMAGE_NAME="amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2"
0.7. インスタンスプロファイル名¶
作成するEC2インスタンスのが利用するインスタンスプロファイル名を指定します。
変数の設定:
IAM_INSTANCE_PROFILE_NAME="EC2InstanceProfileEnvMaint"
0.8. EC2インスタンスのユーザデータファイル名¶
作成するEC2インスタンスのユーザデータファイル名を指定します。
変数の設定:
FILE_INPUT="${HOME}/tmp/conf-ec2/postgresql.bash"
再確認¶
設定されている変数の内容を再確認します。
変数の確認:
cat << ETX # 0.a. AWS_DEFAULT_PROFILE: <EC2のフル権限を許可されたプロファイル> AWS_DEFAULT_PROFILE="${AWS_DEFAULT_PROFILE}" # 0.b. AWS_DEFAULT_REGION: ap-northeast-1 AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" # 0.1. EC2_INSTANCE_TAG_NAME: handson-cli EC2_INSTANCE_TAG_NAME="${EC2_INSTANCE_TAG_NAME}" # 0.2. EC2_IMAGE_NAME: amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2 EC2_IMAGE_NAME="${EC2_IMAGE_NAME}" # 0.3. VPC_TAG_NAME: vpc-handson-cli VPC_TAG_NAME="${VPC_TAG_NAME}" # 0.4. VPC_SUBNET_TAG_NAME: subnet-public0 VPC_SUBNET_TAG_NAME="${VPC_SUBNET_TAG_NAME}" # 0.5. VPC_SG_NAME: env-maint-db VPC_SG_NAME="${VPC_SG_NAME}" # 0.6. EC2_INSTANCE_TYPE: t2.micro EC2_INSTANCE_TYPE="${EC2_INSTANCE_TYPE}" # 0.7. IAM_INSTANCE_PROFILE_NAME: EC2InstanceProfileEnvMaint IAM_INSTANCE_PROFILE_NAME="${IAM_INSTANCE_PROFILE_NAME}" # 0.8. FILE_INPUT: ${HOME}/tmp/conf-ec2/postgresql.bash FILE_INPUT="${FILE_INPUT}" # 0.9. EC2_KEY_PAIR_NAME: <キーペア名> EC2_KEY_PAIR_NAME="${EC2_KEY_PAIR_NAME}" ETX
1. 前処理¶
1.1. 処理対象の状態確認¶
主処理の実施は、以下の状態であることを前提とします。
前提と異なることが判明した場合、直ちに処理を中止します。
事前条件1: ステータスが"running"のEC2インスタンス"handson-cli"が存在しない。
「ステータスが"running"のEC2インスタンス"handson-cli"が存在しない。」ことを確認します。
コマンド:
aws ec2 describe-instances \ --filters Name=tag-key,Values=${EC2_TAG_KEY} Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ --filters Name=instance-state-name,Values=running \ --query Reservations[].Instances[].InstanceId
結果:
[]
事前条件2: AMI"amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2"が存在する。
「AMI"amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2"が存在する。」ことを確認します。
コマンド:
aws ec2 describe-images \ --filter "Name=name, Values=${EC2_IMAGE_NAME}" \ --query 'Images[].Name'
結果(例):
[ "amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2" ]
事前条件3: VPC"vpc-handson-cli"が存在する。
「VPC"vpc-handson-cli"が存在する。」ことを確認します。
変数の設定:
EC2_TAG_KEY='Name'
コマンド:
aws ec2 describe-vpcs \ --filters Name=tag:${EC2_TAG_KEY},Values=${VPC_TAG_NAME} \ --query "Vpcs[].Tags[].Value"
結果(例):
[ "vpc-handson-cli" ]
VPC IDを取得します。
コマンド:
VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:${EC2_TAG_KEY},Values=${VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${VPC_ID}
結果(例):
vpc-xxxxxxxx
事前条件4: VPC"vpc-handson-cli"にサブネット"subnet-public0"が存在する。
「VPC"vpc-handson-cli"にサブネット"subnet-public0"が存在する。」ことを確認します。
変数の設定:
EC2_TAG_KEY='Name'
コマンド:
aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${VPC_ID} \ --filters Name=tag:${EC2_TAG_KEY},Values=${VPC_SUBNET_TAG_NAME} \ --query "Subnets[].Tags[].Value"
結果(例):
[ "subnet-public0" ]
事前条件5: VPC"vpc-handson-cli"にセキュリティグループ"env-maint-db"が存在する。
「VPC"vpc-handson-cli"にセキュリティグループ"env-maint-db"が存在する。」ことを確認します。
変数の設定:
EC2_TAG_KEY='Name'
コマンド:
aws ec2 describe-security-groups \ --filter Name=vpc-id,Values=${VPC_ID} \ Name=group-name,Values=${VPC_SG_NAME} \ --query 'SecurityGroups[].GroupName'
結果(例):
[ "env-maint-db" ]
事前条件6: インスタンスプロファイル"EC2InstanceProfileEnvMaint"が存在する。
「インスタンスプロファイル"EC2InstanceProfileEnvMaint"が存在する。」ことを確認します。
コマンド:
aws iam list-instance-profiles \ --query "InstanceProfiles[?InstanceProfileName == \`${IAM_INSTANCE_PROFILE_NAME}\`].InstanceProfileName"
結果(例):
[ "EC2InstanceProfileEnvMaint" ]
事前条件7: ユーザデータ"${HOME}/tmp/conf-ec2/postgresql.bash"が存在する。
「ユーザデータ"${HOME}/tmp/conf-ec2/postgresql.bash"が存在する。」ことを確認します。
コマンド:
ls ${FILE_INPUT}
結果(例):
${HOME}/tmp/conf-ec2/postgresql.bash
事前条件8: キーペア"<キーペア名>"が存在する。
「キーペア"<キーペア名>"が存在する。」ことを確認します。
コマンド:
aws ec2 describe-key-pairs \ --key-names ${EC2_KEY_PAIR_NAME}
結果(例):
{ "KeyPairs": [ { "KeyName": "<キーペア名>", "KeyFingerprint": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" } ] }
1.2. 主処理に必要な情報の取得¶
イメージIDの取得
イメージIDを取得します。
コマンド:
EC2_IMAGE_ID=$( \ aws ec2 describe-images \ --filters Name=name,Values="${EC2_IMAGE_NAME}" \ --query 'Images[].ImageId' \ --output text \ ) \ && echo ${EC2_IMAGE_ID}
結果(例):
ami-XXXXXXXX
サブネットIDの取得
サブネットIDを取得します。
コマンド:
VPC_SUBNET_ID=$( \ aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${VPC_ID} \ --filters Name=tag:${EC2_TAG_KEY},Values=${VPC_SUBNET_TAG_NAME} \ --query "Subnets[].SubnetId" \ --output text \ ) \ && echo ${VPC_SUBNET_ID}
結果(例):
subnet-xxxxxxxx
セキュリティグループIDの取得
セキュリティグループIDを取得します。
コマンド:
VPC_SG_ID=$( \ aws ec2 describe-security-groups \ --filter Name=vpc-id,Values=${VPC_ID} \ Name=group-name,Values=${VPC_SG_NAME} \ --query "SecurityGroups[].GroupId" \ --output text \ ) \ && echo ${VPC_SG_ID}
結果(例):
sg-xxxxxxxx
セキュリティグループの配列化
変数の設定:
ARRAY_VPC_SG_IDS="${VPC_SG_ID}" \ && echo ${ARRAY_VPC_SG_IDS}
タグ設定文字列の生成
変数の設定:
STRING_TAG_CONF="ResourceType=instance,Tags=[{Key=${EC2_TAG_KEY},Value=${EC2_INSTANCE_TAG_NAME}}]" \ && echo ${STRING_TAG_CONF}
結果(例):
ResourceType=string,Tags=[{Key=${Name},Value=${handson-cli}}
2. 主処理¶
EC2インスタンスの作成¶
変数の確認:
cat << ETX # EC2_IMAGE_ID: ami-2a69be4c EC2_IMAGE_ID="${EC2_IMAGE_ID}" # EC2_INSTANCE_TYPE: t2.micro EC2_INSTANCE_TYPE="${EC2_INSTANCE_TYPE}" # VPC_SUBNET_ID: subnet-xxxxxxxx VPC_SUBNET_ID="${VPC_SUBNET_ID}" # ARRAY_VPC_SG_IDS: sg-xxxxxxxx ARRAY_VPC_SG_IDS="${ARRAY_VPC_SG_IDS}" # STRING_TAG_CONF: ResourceType=instance,Tags=[{Key=Name,Value=handson-cli}] STRING_TAG_CONF="${STRING_TAG_CONF}" # IAM_INSTANCE_PROFILE_NAME: EC2InstanceProfileEnvMaint IAM_INSTANCE_PROFILE_NAME="${IAM_INSTANCE_PROFILE_NAME}" # FILE_INPUT: ${HOME}/tmp/conf-ec2/postgresql.bash FILE_INPUT="${FILE_INPUT}" # EC2_KEY_PAIR_NAME: <キーペア名> EC2_KEY_PAIR_NAME="${EC2_KEY_PAIR_NAME}" ETX
コマンド:
aws ec2 run-instances \ --image-id ${EC2_IMAGE_ID} \ --instance-type ${EC2_INSTANCE_TYPE} \ --subnet-id ${VPC_SUBNET_ID} \ --security-group-ids ${ARRAY_VPC_SG_IDS} \ --tag-specifications ${STRING_TAG_CONF} \ --iam-instance-profile Name=${IAM_INSTANCE_PROFILE_NAME} \ --user-data file://${FILE_INPUT} \ --associate-public-ip-address \ --key-name ${EC2_KEY_PAIR_NAME}
結果(例):
{ "OwnerId": "XXXXXXXXXXXX", "ReservationId": "r-xxxxxxxx", "Groups": [], "Instances": [ { "Monitoring": { "State": "disabled" }, "PublicDnsName": "", "RootDeviceType": "ebs", "State": { "Code": 0, "Name": "pending" }, "EbsOptimized": false, "LaunchTime": "20180108T01:23:45.000Z", "PrivateIpAddress": "xxx.xxx.xxx.xxx", "ProductCodes": [], "VpcId": "vpc-xxxxxxxx", "StateTransitionReason": "", "InstanceId": "i-xxxxxxxx", "ImageId": "ami-xxxxxxxx", "PrivateDnsName": "ip-xxx-xx-xx-xxx.ap-northeast-1.compute.internal", "KeyName": "<キーペア名>", "SecurityGroups": [ { "GroupName": "env-maint-db", "GroupId": "sg-xxxxxxxx" } ], "ClientToken": "", "SubnetId": "subnet-xxxxxxxx", "InstanceType": "t2.micro", "NetworkInterfaces": [ { "Status": "in-use", "MacAddress": "xx:xx:xx:xx:xx:xx", "SourceDestCheck": true, "VpcId": "vpc-xxxxxxxx", "Description": "", "NetworkInterfaceId": "eni-xxxxxxxx", "PrivateIpAddresses": [ { "PrivateDnsName": "ip-xxx-xx-xx-xxx.ap-northeast-1.compute.internal", "Primary": true, "PrivateIpAddress": "xxx.xxx.xxx.xxx" } ], "PrivateDnsName": "ip-xxx-xx-xx-xxx.ap-northeast-1.compute.internal", "Attachment": { "Status": "attaching", "DeviceIndex": 0, "DeleteOnTermination": true, "AttachmentId": "eni-attach-xxxxxxxx", "AttachTime": "20180108T01:23:45.000Z" }, "Groups": [ { "GroupName": "env-maint-db", "GroupId": "sg-xxxxxxxx" } ], "SubnetId": "subnet-xxxxxxxx", "OwnerId": "XXXXXXXXXXXX", "PrivateIpAddress": "xxx.xxx.xxx.xxx" } ], "SourceDestCheck": true, "Placement": { "Tenancy": "default", "GroupName": "", "AvailabilityZone": "ap-northeast-1a" }, "Hypervisor": "xen", "BlockDeviceMappings": [], "Architecture": "x86_64", "StateReason": { "Message": "pending", "Code": "running" }, "RootDeviceName": "/dev/xvda", "VirtualizationType": "hvm", "AmiLaunchIndex": 0 } ] }
3. 後処理¶
3.1. 状態確認に必要な情報の取得¶
インスタンスIDの取得
コマンド:
EC2_INSTANCE_ID=$( \ aws ec2 describe-instances \ --filters Name=tag-key,Values=${EC2_TAG_KEY} Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ --filters Name=instance-state-name,Values=running \ --query Reservations[].Instances[].InstanceId \ --output text \ ) \ && echo ${EC2_INSTANCE_ID}
結果(例):
i-xxxxxxxxxxxxxxxxx
完了条件の確認¶
主処理は、以下を満たしたときに成功したものとします。
完了条件1: ステータスが"running"のEC2インスタンス"handson-cli"が存在する。
「ステータスが"running"のEC2インスタンス"handson-cli"が存在する。」ことを確認します。
コマンド:
aws ec2 describe-instances \ --filters Name=tag-key,Values=${EC2_TAG_KEY} Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ --filters Name=instance-state-name,Values=running \ --query Reservations[].Instances[].InstanceId
結果(例):
[ "i-xxxxxxxxxxxxxxxxx" ]
3.3. 後処理に必要な作業¶
後処理に必要な作業があれば実施します。
コマンド:
EC2_PUBLIC_IP=$( \ aws ec2 describe-instances \ --instance-id ${EC2_INSTANCE_ID} \ --query "Reservations[].Instances[].PublicIpAddress" \ --output text \ ) \ && echo ${EC2_PUBLIC_IP}
結果(例):
xxx.xxx.xxx.xxx