EMRをVisual Studio Codeから起動するスクリプト (コロナ禍対応)

Visual Studio CodeからEMRを使う方法として今はJupyterHubへの接続をしています。

毎回、EMR設定、立ち上げを行うのは面倒なので、スクリプトを書きました。

## Security Groupの設定

昨今、毎回、IPが変わるようなシチュエーションも想定されるため、クライアントアドレスを自動的に送信して所望のアクセスを得ます。

```bash
sg_name=sg-hoge

# delete existing security group
sg=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=vpc-******* Name=group-name,Values=$sg_name --query 'SecurityGroups[*].[GroupId]' --profile prof)
aws ec2 delete-security-group --group-id $sg --profile prof

# create security group
echo creating security group ... : $sg_name
sg=$(aws ec2 create-security-group --group-name $sg_name --description "new security group" --vpc-id vpc-******** --profile prof)
ip=$(curl https://checkip.amazonaws.com)

echo security group id : $sg
echo client IP address : $ip

aws ec2 authorize-security-group-ingress --group-id $sg --protocol tcp --port 22 --cidr $ip/32 --profile prof # ssh
aws ec2 authorize-security-group-ingress --group-id $sg --protocol tcp --port 9443 --cidr $ip/32 --profile prof # jupyter
aws ec2 authorize-security-group-ingress --group-id $sg --protocol tcp --port 80 --cidr 10.0.0.0/16 --profile prof # http
aws ec2 authorize-security-group-ingress --group-id $sg --protocol tcp --port 443 --cidr 10.0.0.0/16 --profile prof # https
aws ec2 describe-security-groups --group-ids $sg --profile prof
echo waiting security group ...
aws ec2 wait security-group-exists  --group-ids $sg --profile adsp

```

## EMRクラスタの立ち上げ

こちらも、前回の同名クラスタがあれば削除するようにしています。
細かいクラスタ設定は --configurations に渡す設定ファイルに記載します。


``` bash
cluster_name = "hoge_cluster"

# delete existing cluster
active_cluster_id=$(aws emr list-clusters --query 'Clusters[?Name==`'"$cluster_name"'`]|[?contains(Status.State, `TERMINATED`) == `false`].[Id]' --profile prof)
aws emr terminate-clusters --cluster-ids $active_cluster_id --profile prof
aws emr wait cluster-terminated --cluster-ids $active_cluster_id --profile prof

# create cluster
numnodes=10
master_instance_type=m5.16xlarge

cluster_ids=$( \
aws emr create-cluster \
    --name $cluster_name \
    --release-label emr-5.30.1 \
    --applications Name=Hadoop Name=Spark Name=Livy Name=Hive Name=JupyterHub \
    --instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=$master_instance_type InstanceGroupType=CORE,InstanceCount=$numnodes,InstanceType=m4.large \
    --log-uri s3n://aws-******/elasticmapreduce/ \
    --service-role EMR_DefaultRole \
    --auto-scaling-role EMR_AutoScaling_DefaultRole \
    --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole,SubnetId=subnet-01b77e396474dfba1,KeyName=masutani-ec2,EmrManagedMasterSecurityGroup=$sg,EmrManagedSlaveSecurityGroup=$sg \
    --configurations file://./emr.json \
    --profile prof)

cluster_arn=$(cut -f 1 <<< ${cluster_ids})
cluster_id=$(cut -f 2 <<< ${cluster_ids})
echo Starting EMR clsuter ID : $cluster_id ...
aws emr wait cluster-running --cluster-id $cluster_id --profile prof
aws emr ssh --cluster-id $cluster_id --key-pair-file ~/.ssh/ec2.pem --profile prof

master_dns=$(aws emr describe-cluster --cluster-id $cluster_id --output json --query 'Cluster.MasterPublicDnsName' --profile prof)
echo Master DNS name : $master_dns
echo jupyter URL: $master_dns:9443/

```

## Visual Studio Code タスク化

VSCodeで使うので、是非タスク化しましょう。
task.jsonに以下のようにスクリプトを指し示すように記述すれば大丈夫です。
ただ、起動するだけで、まだVSCodeのプラグインへの自動設定などの仕方がわかりません。orz

```json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "emr: start cluster",
            "detail": "launch EMR Cluster",
            "type": "shell",
            "command": "/mnt/${workspaceFolder}/setupemr.sh",
            "windows": {
              "command": "/mnt/.../setupemr.sh"
            },
            "presentation": {
              "reveal": "always",
              "panel": "new"
            }
        },
    ]
}
```