EC2 instance起動時にtagをつけるTagSpecifications

AWSCLIでEC2 instance起動時に同時にタグをつける方法としては、instance起動してinstance-idを取得しておいて、パイプでつないでtagをつけたり、スクリプトの中で後でタグ付けする方法があったと思います。
http://kurochan-note.hatenablog.jp/entry/2017/01/08/220155

AWSCLI EC2 Run-Instanceのなかに–tag-specificationsというoptionが入って、run-instancesの中でタグが作成できるようになりました。地味なアップデートかもしれませんが、結構うれしいです。

instanceの詳細はjsonに記述して、下記のように指定して実行します。

aws ec2 run-instances --cli-input-json file://instance.json

EC2は山ほど設定項目があるので、generate-cli-skeltonでフォーマットを出力して、必要な項目だけ入力して、不必要なものは消すとinstanceの詳細を記述したjsonの完成です。Gitにでも入れておきましょう。
http://docs.aws.amazon.com/cli/latest/userguide/generate-cli-skeleton.html

aws ec2 run-instances --generate-cli-skeleton

Instanceの設定詳細を記述したjsonサンプル

instance.json
{
    "ImageId": "<image-id>",
    "KeyName": "<my-key>",
    "SecurityGroupIds": [
        "<my-sgid>"
    ],
    "InstanceType": "<instance-type>",
    "BlockDeviceMappings": [
        {
            "VirtualName": "Root",
            "DeviceName": "/dev/sda1",
            "Ebs": {
                "VolumeSize": 100,
                "DeleteOnTermination": true,
                "VolumeType": "gp2"
            }
        }
    ],
    "Monitoring": {
        "Enabled": false
    },
    "SubnetId": "<subnet-id>",
    "DisableApiTermination": false,
    "IamInstanceProfile": {
        "Name": "<instance-iam-role>"
    },
    "TagSpecifications":[
        {
            "ResourceType": "instance",
            "Tags": [
              {
                "Key": "Name",
                "Value": "<server-name>"
              },
              {
                "Key": "ClusterName",
                "Value": "<cluster-name>"
              },
              {
                "Key": "Application",
                "Value": "<myapp>"
              },
              {
                "Key": "CostCenter",
                "Value": "<my-cost-center>"
              },
              {
                "Key": "Environment",
                "Value": "Test"
              },
              {
                "Key": "User",
                "Value": "<user-name>"
              }
            ]
        },
        {
          "ResourceType": "volume",
          "Tags": [
            {
              "Key": "Device",
              "Value": "<device-name>"
            },
{
              "Key": "CostCenter",
              "Value": "<my-cost-center>"
            },
            {
              "Key": "backup_key",
              "Value": "true"
            }
          ]
        }
    ]
}

続きを読む

OpenFoam on AWS Batch

2016年末にリリースされたAWSの新サービスBatchを使ってOpenFoamを実行してみました。
openfoam-batch.png

Build OpenFoam Docker Images

ubuntu14.04をベースにして、OpenFoam4.1とParaView5.0をインストールします。
その後AWSCLIをインストールします。OpenFoamで計算した結果をS3に保存するためです。
実際にOpenFoamを実行するShellスクリプトはGithubからダウンロードしてきます。

https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/Dockerfile

Dockerfile
#OpenFOAM 4.1 and ParaView 5.0.1 on ubuntu 14.04
FROM ubuntu:trusty

MAINTAINER Hiroshi.Kobayashi

WORKDIR /root

RUN set -x && 

    # install openfoam
    sudo apt-get -y update && 
    sudo apt-get -y upgrade && 
    sudo apt-get -y install apt-file && 
    sudo apt-get -y install software-properties-common && 
    sudo add-apt-repository http://dl.openfoam.org/ubuntu && 
    sudo apt-get -y install wget && 
    sudo wget -O - http://dl.openfoam.org/gpg.key | apt-key add - && 
    sudo apt-get -y install apt-transport-https && 
    sudo apt-get -y update && 
    sudo apt-get -y install openfoam4 && 
    sudo echo "source /opt/openfoam4/etc/bashrc" >> /root/.bashrc && 

    # install awscli
    sudo curl -O https://bootstrap.pypa.io/get-pip.py && 
    sudo python3 get-pip.py --user && 
    export PATH=/root/.local/bin:$PATH && 
    /bin/bash -c "source /root/.bashrc" && 
    pip install awscli --upgrade --user

ENV AWS_DEFAULT_REGION=us-east-1 
    AWS_DEFAULT_OUTPUT=json

ADD https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/openfoam_run.sh /root
RUN sudo chmod +x /root/openfoam_run.sh
CMD ["/root/openfoam_run.sh"]

今回はopenfoam-dockerと名前をつけてbuildします。私のMacbook Airで15分くらいかかりました。
docker build -t openfoam-docker:latest .

実際に計算するモデルはチュートリアルから持ってきました。 “incompressible/simpleFoam/pitzDaily”
simpleFoam_pitzDaily_mesh.png simpleFoam_pitzDaily_contor.png

Push Image to AWS ECR

1) Retrieve the docker login command that you can use to authenticate your Docker client to your registry:
aws ecr get-login --region us-east-1
2) Run the docker login command that was returned in the previous step.
3) After the build completes, tag your image so you can push the image to this repository:
docker tag openfoam-docker:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/<ecr-name>:latest
4) Run the following command to push this image to your newly created AWS repository:
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/<ecr-name>:latest

docker_push.png.png

Create AWS Batch Environment

1) create job definition
aws batch register-job-definition --cli-input-json file://<path>/job_definition.json
https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/job_definition.json

{
    "jobDefinitionName": "openfoam-docker-job",
    "type": "container",
    "parameters": {},
    "containerProperties": {
        "image": "<account-id>.dkr.ecr.us-east-1.amazonaws.com/<ecr-name>",
        "vcpus": 1,
        "memory": 500,
        "command": [],
        "attempts": 3,
        "jobRoleArn": "arn:aws:iam::<account-id>:role/openfoam-docker-job-role",
        "volumes": [],
        "environment": [],
        "mountPoints": [],
        "ulimits": []
    }
}

2) create computing environment
aws batch create-compute-environment --cli-input-json file://<path>/computing_env.json
https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/computing_env.json

{
  "computeEnvironmentName": "M3Spot",
  "type": "MANAGED",
  "state": "ENABLED",
  "computeResources": {
    "type": "SPOT",
    "spotIamFleetRole": "arn:aws:iam::<account-id>:role/aws-ec2-spot-fleet-role",
    "minvCpus": 1,
    "maxvCpus": 10,
    "desiredvCpus": 1,
    "instanceTypes": [
      "m3"
    ],
    "bidPercentage": 40,
    "subnets": [
      "subnet-XXXXXXXX",
      "subnet-XXXXXXXX",
      "subnet-XXXXXXXX",
      "subnet-XXXXXXXX"
    ],
    "securityGroupIds": [
      "sg-XXXXXXXX"
    ],
    "ec2KeyPair": "<your-key-pair>",
    "instanceRole": "<your-role>"
  },
  "serviceRole": "arn:aws:iam::<account-id>:role/service-role/AWSBatchServiceRole"
}

3) create job queue
aws batch create-job-queue --cli-input-json file://<path>/job_queue.json
https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/job_queue.json

{
  "jobQueueName": "openfoam-docker-queue",
  "state": "ENABLED",
  "priority": 1,
  "computeEnvironmentOrder": [
    {
      "order": 1,
      "computeEnvironment": "M3Spot"
    }
  ]
}

Submit Jobs

AWSCLIで同じジョブを回数指定して10秒おきにsubmitします。

bash
#!/bin/bash
QUEUE="openfoam-docker-queue"
JOBDEF="openfoam-docker-job"
MAXITR=10

for i in `seq 1 $MAXITR`
do
  JOBNAME="JOB_$i"
  aws batch submit-job --job-name $JOBNAME --job-queue $QUEUE --job-definition $JOBDEF
  echo "submitted $JOBNAME"
  sleep 10
done

実際にはDocker Imageに埋め込んであるshellスクリプトが実行されます。
流速の結果が格納されているU fileをS3に転送します。

bash
#!/bin/bash

# geting JOB ID, bucket name
BUCKETNAME="<bucket-name>"

# run OpenFoam4 with tutrial model "pitzDaily"
source /opt/openfoam4/etc/bashrc
source /root/.bashrc
export PATH=/root/.local/bin:$PATH

cd /root
mkdir -p $FOAM_RUN
cd $FOAM_RUN
cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily .
cd pitzDaily
blockMesh
simpleFoam

# upload U to S3
TIMESTAMP=`date +%Y%m%d%H%M%S%N`
aws s3 cp ./298/U s3://$BUCKETNAME/$TIMESTAMP

Check the result on S3

go to S3 and check the U files

参考資料

http://qiita.com/pottava/items/d9886b2e8835c5c0d30f
http://qiita.com/pottava/items/452bf80e334bc1fee69a
https://openfoam.org/download/4-1-ubuntu/
http://docs.aws.amazon.com/cli/latest/reference/batch/index.html#cli-aws-batch
http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html

続きを読む

re:Invent 2016 私的HPCまとめ

AWS re:Invent 2016に参加してきました。他の誰もやらないHPC的なまとめを私なりにしてみます。

AWS re:Inventについて

私が説明するよりもはるかに素晴らしい紹介コンテンツが山ほどあるので、そちらを参照ください。
毎年参照するのがクラスメソッド様の全セッションまとめです。毎年お世話になります。
http://dev.classmethod.jp/cloud/aws/reinvent-2016-matome/

KeyNote

New Instance Type

新しいインスタンスタイプのリリース、skylake世代がAWSにやってきます。
c5, r4なんかはベンチマークが非常に楽しみです。i3なんかもClusterの共有ファイルサーバとしてI/Oが改善されているので非常に楽しみです。でもやっぱり一番熱いのはf1インスタんですね。FPGAがAWSにやってくるとは思っていませんでした。MentorとかSynopsysとかEDAをぶん回したいですね。

Elastic GPU

g2インスタンスはGPUの性能は非常にいいのですが、CPUやメモリの性能バアランスがよくないなーと常々思ってて、というかGPUオーバープロビジョンじゃないって感じてました。Elastic GPUのおかげで自分でバランスとることができるのでうれしいです。3D Renderingの性能はやっぱすこし落ちるのかな?ちょっとそこが心配です。

AWS Batch

これは正直やばいサービス、HPC Cloud Service Killerです。神速でプレビュー申し込みましたが、まだ使えてないです。GAが非常に楽しみです。

HPCおすすめセッション

AWS re:Invent 2016: Deep Dive on Amazon EC2 Instances, Featuring Performance Optimization (CMP301): https://www.youtube.com/watch?v=agQMFIWr2h4

AWS re:Invent 2016: Save up to 90% and Run Production Workloads on Spot (CMP307) : https://www.youtube.com/watch?v=PZFa83QA6UE

AWS re:Invent 2016: Revolutionizing Car Buying with 3D Rendering on Amazon EC2 (CMP313) : https://www.youtube.com/watch?v=0UWLMIFhBIk

AWS re:Invent 2016: Bringing Deep Learning to the Cloud with Amazon EC2 (CMP314) : https://www.youtube.com/watch?v=34Xorby_pyw

AWS re:Invent 2016: Optimizing Network Performance for Amazon EC2 Instances (CMP315) : https://www.youtube.com/watch?v=CBmSl3O-AhI&feature=youtu.be

AWS re:Invent 2016: Building HPC Clusters as Code in the (Almost) Infinite Cloud( CMP318 ) : https://www.youtube.com/watch?v=x7M3m1jZ7L8

AWS re:Invent 2016: Massively Parallel, Compute Intensive Workloads in the Cloud (CMP317) : https://www.youtube.com/watch?v=3equT56K1Xs

AWS re:Invent 2016: NEW LAUNCH! Delivering Graphics-Intensive Applications from AWS Cloud (CMP320) : https://www.youtube.com/watch?v=MSVe8L6Mmjs&feature=youtu.be

AWS re:Invent 2016: Building SaaS Offerings for Desktop Apps with Amazon AppStream 2.0 (CMP321) : https://www.youtube.com/watch?v=69PGgSvHOEo&feature=youtu.be

AWS re:Invent 2016: NEW LAUNCH! Introducing AWS Batch: Easy and efficient batch computing (CMP323) : https://www.youtube.com/watch?v=ebwfhSS4ZkY&feature=youtu.be

所感

実はセッションはほとんでライブで見れませんでした。Vendorとのmeetingやラスベガスにあるデータセンターの見学なんかをしていました。そういう意味でライブ感を味わえてないのは残念でした。

いろいろなサービスが充実してきて、ほうとうにHPCをAWS上で構築しても何の問題もないレベルまできてる思います。データ転送、MPI並列性能、クラウド上での3D Visualization。すべてがAWS上でハイレベルに構築可能です。あとはソフトウェアのライセンスがAWSのようなFlexisibilityをもったものがたくさん出てくるとより一層クラウド化がすすむと思います。

特にAWSがNICE Softwareを買収して、NICE DCVというリモートの3D RenderingのテクノロジーがどうAWSに組み込まれていくのか楽しみにしてましたが、それがAppStream2.0としてHTML5ベースになって登場したのは嬉しい限りです。

今後はEC2だけでなくECSがHPCにどうやって使われていくかウォッチしていきたいと思います。やっぱコンテナ便利だし、AWS BatchでもサポートされるのでECS-Batch-Spotのコンボでとても面白いことができるのではないかと感じております。

あとDeep LearningもHPC的に必修科目だなと痛感しました。TensorFlowとか触ったこともないけど。。。勉強します。Deep Learning系はライブラリ系揃えるのがめんどくさいからECS-Batch-Spotのコンボが有効なんだろうなと思います。

私は引き続き社内のHPCリソースを粛々とAWSに追い出していきたいと思います。今後とも宜しくお願いします。

続きを読む

EBS snapshot automation

0. はじめに

EC2がなにかと増えてきて、EBSのスナップショットの容量、個数が増えてきて、Human Errorが出る前に自動化しときたいなーと思っていた所、こちらの記事(http://qiita.com/MasaoDX/items/39624823fff337d08e6f) を参考にさせていただきました。

AWSCLIで
1.バックアップターゲットEBSの検索
2.Snapshot作成
3.保持期間,VolumeID,device name等の情報をsnapshotに付加
4.消してもOKなsnapshotを検索して削除
5.snapshotをとったvolumeをAWSSNSで通知

0. System Requirement

1. IAM Roleの準備

Snapshotを作ったり消したりするためだけのIAM Roleを設定します。権限を最低限に抑えるのがお作法だと聞いております。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateDeleteSnapshot",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot",
                "ec2:CreateImage",
                "ec2:CreateTags",
                "ec2:DescribeImages",
                "ec2:DeregisterImage"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

2. AWS CLI実行用のInstance準備

2.1 Amazon Linuxの起動 with IAM Role

  • IAM Roleに1で作成したIAM RoleをつけてInstanceを起動します
  • IAM Roleの割り当ては初回起動時にしかできないのでご注意を

2.2 jq install

sudo yum install jq

3. EBS側の準備

3.1 Tag付け

  • バックアップのターゲットになるEBSにtagをつけます。このタグで検索してバックアップを実行します。

    Key = backup_target
    Value = true

4. 実行するシェルスクリプト

4.1 変数定義

DATE_CURRENT=`date +%Y-%m-%d`
TIME_CURRENT=`date +%Y%m%d%H%M%S`
PURGE_AFTER_DAYS=0
PURGE_AFTER=`date -d +${PURGE_AFTER_DAYS}days -u +%Y-%m-%d`
BACKUP_KEY='backup_target'
AWS_REGION='us-west-2'
SNS_REGION='us-west-2'
SNS_TOPIC_NAME='MySNSTopic'
SNS_TOPIC_ARN=`aws --region ${SNS_REGION} sns list-topics | jq -r .Topics[].TopicArn | grep ${SNS_TOPIC_NAME}`
ERROR_VOL='./error_vol.txt'
SUCCESS_VOL='./succes_vol.txt'

4.2 Snapshotの作成

# 1-1. listing-up backup target volume-id
VOLUMES=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=tag:${BACKUP_KEY},Values=true | jq -r '.Volumes[].Attachments[] | .VolumeId'`

for VOLUME in ${VOLUMES}; do
  BACKUP=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=volume" "Name=resource-id,Values=${VOLUME}" "Name=key,Values=${BACKUP_KEY}" | jq -r .Tags[].Value`
  INSTANCE_ID=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=volume-id,Values=${VOLUME} | jq -r '.Volumes[].Attachments[] | .InstanceId'`
  Device_Name=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=volume-id,Values=${VOLUME} | jq -r '.Volumes[].Attachments[] | .Device'`
  INSTANCE_NAME=`aws --region ${AWS_REGION} ec2 describe-tags --filters Name=resource-id,Values=${INSTANCE_ID} Name=key,Values=Name | jq -r .Tags[].Value`

  # 1-2.verify backup target volume with tag
  if [ "${BACKUP}" == "true" ]; then
    # 1-3.create snapshot
    SNAPSHOT_ID=`aws --region ${AWS_REGION} ec2 create-snapshot --volume-id ${VOLUME} --description "${INSTANCE_NAME} ${INSTANCE_ID} ${Device_Name} ${VOLUME} ${TIME_CURRENT}" | jq -r '.SnapshotId'`
      if [ -z "${SNAPSHOT_ID}" ]; then
        echo ${VOLUME} >> "${ERROR_VOL}"
      else
        echo ${VOLUME} >> "${SUCCESS_VOL}"
      fi
    # 1-4.adding tag for searching
    aws --region ${AWS_REGION} ec2 create-tags --resources ${SNAPSHOT_ID} --tags Key=PurgeAllow,Value=true Key=PurgeAfter,Value=${PURGE_AFTER} Key=PurgeTarget,Value=${BACKUP_KEY} Key=Name,Value="${INSTANCE_NAME} ${INSTANCE_ID} ${Device_Name} ${VOLUME} ${TIME_CURRENT}"
  fi
done

4.3 Snapshotの削除

# 2-1.find delete target snapshot volume with tag
SNAPSHOT_PURGE_ALLOWED=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=key,Values=PurgeAllow" | jq -r .Tags[].ResourceId`

# 2-2. verify the delete target volumes with 2 tags
for SNAPSHOT_ID in ${SNAPSHOT_PURGE_ALLOWED}; do
  PURGE_AFTER_DATE=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=resource-id,Values=${SNAPSHOT_ID}" "Name=key,Values=PurgeAfter" | jq -r .Tags[].Value`
  PURGE_TARGET_CHECK=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=resource-id,Values=${SNAPSHOT_ID}" "Name=key,Values=PurgeTarget" | jq -r .Tags[].Value`

  if [ "${PURGE_TARGET_CHECK}" == "${BACKUP_KEY}" ]; then

    if [ -n ${PURGE_AFTER_DATE} ]; then
      DATE_CURRENT_EPOCH=`date -d ${DATE_CURRENT} +%s`
      PURGE_AFTER_DATE_EPOCH=`date -d ${PURGE_AFTER_DATE} +%s`

      if [[ ${PURGE_AFTER_DATE_EPOCH} < ${DATE_CURRENT_EPOCH} ]]; then
        # 2-2.judge the target and delete the snapshots
        aws --region ${AWS_REGION} ec2 delete-snapshot --snapshot-id ${SNAPSHOT_ID}
      fi
    fi
  fi
done

4.3 SNSで結果報告

#3-1. send notification mail
if [ -e "${ERROR_VOL}" ]; then
# create message header
cat << EOF >> ${ERROR_VOL}

There are EBS volumes failed to take snapshots on above volumes, please contact to AWS admin

EOF
  date >> ${ERROR_VOL}
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message file://tokyo_error_vol.txt --subject "[ERROR] EBS Backup"
rm -f ${ERROR_VOL}

elif [ -e "${SUCCESS_VOL}" ]; then
# create message header
cat << EOF >> ${SUCCESS_VOL}

Taking EBS snapshot was succesfully completed on above volumes. Have a nice day!

EOF
  date >> ${SUCCESS_VOL}
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message file://tokyo_succes_vol.txt --subject "[SUCCESS] EBS Backup"
  rm -f ${SUCCESS_VOL}

else
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message "There are no target EBS Volumes" --subject "[WARN] EBS Backup"
  rm -f ${SUCCESS_VOL}
fi

5. cronで定期実行

書いたシェルスクリプトをcronで定期実行してあげる。例えばこんな感じに。

00 01 * * 0 ~/backup.sh >> /var/log/cron.log

続きを読む

[JAWS-UG HPC] CfnCluster ハンズオン 事前準備 IAM編

IAMの設定

CfnClusterを使ってクラスターを構築するとき(http://qiita.com/daikumatan/items/23b36199fc6872c78dc0) のために、ひとつIAMユーザを準備します。

  • AWSマネージメントコンソールからIdentity & Access Management(略してIAM)を選択
    スクリーンショット_012216_022058_AM.jpg

Userの作成

  • Users -> Create New Users
    スクリーンショット_012216_022607_AM.jpg

  • ユーザ名を入力し、Createをクリック
    スクリーンショット_012216_022819_AM.jpg

  • 作成したユーザのクレデンシャルを確認、

  • Access Key IDとSecret Access Keyの値をメモるかダウンロードする
    スクリーンショット_012216_023256_AM.jpg

Groupの作成

  • Groups -> Create New Group
    スクリーンショット_012216_023609_AM.jpg

  • Group名を入力
    スクリーンショット_012216_023759_AM.jpg

  • Groupに権限を定義

  • cfnclsuetrは裏でいろんなサービスが動いているのでまじめに権限設定すると面倒くさいので、ここではフル権限のAdministratorAccess

    スクリーンショット_012216_024137_AM.jpg

  • 内容確認して、Create Groupをクリック
    スクリーンショット_012216_024327_AM.jpg

Userに権限付与

  • 作成したUserを、作成したGroupに加える
    スクリーンショット_012216_024842_AM.jpg
    スクリーンショット_012216_025020_AM.jpg

終わり

  • 以上でIAMユーザの作成と権限設定は完了です。メモ or ダウンロードしたクレデンシャルは無くさないように保管してください。

続きを読む