AWSエンジニアが学習するAlibaba Cloud【Function Compute編 (5)】

普段AWSを主に利用しているエンジニアがAlibabaCloudを学習するために調べた情報や手順を紹介します。

今回の内容は

- start-web-frameworkの紹介(再掲)
- 開発用ECSインスタンスの作成
※Javaフレームワーク(Tomcat/JettyやSpringBoo,Quarkus)をServerless Devsで実装する為の事前準備

となります。

## ■ Disclaimer

本記事は掲載時点の情報であり、最新の情報とは異なる場合があります。
本記事は完全性、正確性、有用性、安全性などを保証するものではありません。
本記事をご利用の場合は自己責任にてお願いします。

## ■ Prerequisites

- Alibaba Cloudアカウントを作成済みであることを前提とします。
  - [Alibaba Cloud アカウントを作成](https://www.alibabacloud.com/help/ja/maxcompute/latest/create-an-alibaba-cloud-account)
- [AWSエンジニアが学習するAlibaba Cloud【Function Compute編 (2)】](https://qiita.com/junk87/items/aa19c264f835c20f40dd)までを実施済みの環境であることを前提とします。

## ■ Overview

### 1. start-web-framework

前回の再掲となりますが、start-web-frameworkはAlibaba Cloudを活用したのWebフレームワーク応用事例となります。
Alibaba CloudのFunction ComputeへWEBフレームワークをデプロイする方法が公開されています。
また、Serverless Devsのプロジェクトのデフォルトレポジトリにもなっているようです。

- start-web-framework
    - https://github.com/devsapp/start-web-framework/blob/master/readme_en.md

現在start-web-frameworkへ公開されているWebフレームワークのデプロイ方法は以下のとおりとなっています。
[start-web-framework](https://github.com/devsapp/start-web-framework/blob/master/readme_en.md)へ表記されているWebフレームワークと違いがありますが正しい表記はこちらとなります。
※[start-web-framework](https://github.com/devsapp/start-web-framework/blob/master/readme_en.md)の表記は修正中のようです

| Node.js   | Python   | PHP   | Go | Java | Others    |
| -- | -- | -- | -- | -- | -- |
| Express [custom]   | Flask [python3]   | Think PHP [custom]   | BeeGo   | Tomcat/Jetty | Gatsby   |
| Egg [custom]   | Tornado [custom]   | Laravel [custom]   | Gin [custom]   | SpringBoot [custom] | Hugo [custom]   |
| Nextjs [custom]   | Bottle [python3]   | Discuz [custom]   | -   | Quarkus | -   |
| Nuxtjs [custom]   | Web.py [python3]   | WordPress [custom]  | - | - | - |
| Hapi [custom]  |  Django [python3] | Zblog [custom] | - | - | - |
| Koa [custom]  |  FastAPI [custom] | Ecshop [custom] | - | - | - |
| Nest [custom]  |  Web2py | Metinfo [custom] | - | - | - |
| Midway-koa [custom]  |  Pyramid [python3] | Whatsns [custom] | - | - | - |
| Vue.js [custom]  |  - | Typecho [custom] | - | - | - |

今回はJavaフレームワークであるTomcat/JettyやSpringBoot、Quarkusをstart-web-frameworkを参考にServerless Devsで実装してみます。

## ■ Let’s Get Started

前回まではCloudShell上よりServerless Devsを実行してきましたが今回からは以下の流れで実装します。

1. 開発用ECSインスタンスを作成
1. Javaフレームワークを実装および開発【開発用ECSインスタンス】
1. 開発したソースコードをServerless Devsを用いてJavaフレームワークへデプロイ【Function Compute】

なお、ECSインスタンスはAWSのEC2インスタンスと同じコンピューティングサービスとなります。
詳細は[ECS の概要](https://www.alibabacloud.com/help/ja/elastic-compute-service/latest/what-is-ecs)をご確認ください

本記事では今後CloudShellを利用することもあり、効率を優先して

[Create and manage an ECS instance by using CLI commands](https://www.alibabacloud.com/help/en/elastic-compute-service/latest/create-and-manage-an-ecs-instance-by-using-cli-commands)

の手順を参考にコマンドラインインターフェイス（CLI）で「開発用ECSインスタンスの作成」を実施します。

CLIでの操作が難しい方はAlibaba Cloudの管理画面のECS管理コンソールより開発用ECSインスタンスを作成していただいてもかまいません。
その場合は下記内容の開発用ECSインスタンスを作成してください。

■ECSインスタンス構成
| 項目| 値 | 備考 |
| -- | -- | -- |
| 課金方法 | Pay-as-you-go | 従量課金 |
| リージョン | 日本(東京) | 東京ゾーンCを指定 |
| インスタンスタイプ | 汎用タイプ g7(ecs.c7.large) | 2vCPU/4GiB ($0.096USD/時間) |
| OSイメージ | CentOS Stream 9 64bit | パブリックイメージ |
| ストレージ| 拡張SSD 20GB| PL1を指定 | 
| VPC | 任意のVPC | デフォルトでも可 | 
| パブリックIP| ■| パブリック IP の割り当てを選択 | 
| 帯域幅 | 1Mbps | 帯域幅課金を選択 |
| セキュリティグループ | 全ての場所からSSH(TCP:22)の通信を許可するセキュリティグループ | |
| ログイン認証 | パスワード | |
| ログイン名 | root | |
| パスワード| 任意のパスワードを指定 | rootユーザーのSSHログインパスワード |
| インスタンス名 | serverlessdevs_local | |

ECS管理コンソールからECSインスタンス作成方法が分からない場合ですが、
AlibabaCloud公式ページ(日本語)やSNSで随時セミナーなどを発信しているようですので参加してみるのもよいかと思います。

- 公式ページ(日本語)
    - https://www.alibabacloud.com/ja
- 公式SNS
    - https://www.facebook.com/AlibabaCloud.jp
    - https://twitter.com/AlibabaCloud_jp

#### 1.1. AlibabaCloudにサインイン

自分のアカウント（メールアドレス）とパスワードを入力の上、【サインイン】をクリックします。

![FunctionCompute_10001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/646bbf8a-6b64-02d8-ead7-3d55f6f5e859.png)

#### 1.2. CloudShellの起動

今回はAlibabaが提供しているCLIのAlibaba Cloud CLI (aliyuncli) をCloudShell上で実行します。AWS でいうAWS CLI (awscli)と同様のCLIとなります。
本手順ではAlibaba Cloud CLI (aliyuncli)の詳細は省略しますが、より詳しく知りたい方は公式ドキュメントやGithubなどをご確認ください。

- Alibaba Cloud CLI
    - https://www.alibabacloud.com/help/en/alibaba-cloud-cli
- GitHub – Alibaba Cloud CLI
    - https://github.com/aliyun/aliyun-cli


画面上のメニューより【CloudShell】をクリックします。

![FunctionCompute_10008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/e978ac8e-20be-b8dd-5ae4-a51fb23dfa3f.png)

画面下にCloudShellのターミナルが表示されていることを確認します。

![FunctionCompute_10009.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/d0372798-de03-e572-45b1-b3e5403256f2.png)

#### 1.3. VPCの作成

ECSインスタンス作成前に

・VPC　(AWS VPCと同様の概念）
・vSwitch（AWSのサブネットと同様の概念）
・セキュリティグループ（AWSのセキュリティグループと同様の概念）

を作成する必要がある為、CloudShellよりCreateVpcコマンドを実行して下記構成のVPCを作成します。

■VPC構成
| 項目| 値 | 備考 |
| -- | -- | -- |
| リージョン | ap-northeast-1 | 日本（東京） |
| CIDR | 192.168.0.0/16 | 既に192.168.0.0/16でVPCを作成している場合は別のCIDRを指定してください |

```bash:CreateVpcコマンド
aliyun vpc CreateVpc \
> --RegionId ap-northeast-1 \
> --CidrBlock 192.168.0.0/16
```

```bash:CreateVPC実行結果
{
        "RequestId": "1D84211B-****-****-****-*********",
        "ResourceGroupId": "rg-acf************",
        "RouteTableId": "vtb-6we1****************",
        "VRouterId": "vrt-6we23****************",
        "VpcId": "vpc-6wep****************"
}
```

CreateVPC実行結果の[VpcId]の値(vpc-6wep****************の箇所)は他のコマンドで利用する為、控えておきます。

#### 1.4. VSwitchの作成

VPCを作成後、CloudShellよりCreateVSwitchコマンドを実行して下記構成のVSwitchを作成します。

■vSwitch構成
| 項目| 値 | 備考 |
| -- | -- | -- |
| リージョン | ap-northeast-1 | 日本（東京） |
| CIDRブロック | 192.168.0.0/24 |VPCのCIDR範囲内を指定 |
| ゾーンID | ap-northeast-1c | 東京ゾーンC |
| VPC ID | vpc-6wep**************** | CreateVPC実行結果の[VpcId]の値 |

```bash:CreateVSwitchコマンド
aliyun vpc CreateVSwitch \
--CidrBlock 192.168.0.0/24 \
--RegionId ap-northeast-1 \
--VpcId vpc-6wep**************** \
--ZoneId=ap-northeast-1c
```
※VpcIdの値(vpc-6wep****************)はCreateVPC実行結果の[VpcId]の値に置き換えてください

```bash:CreateVSwitch実行結果
{
        "RequestId": "F73D287B-****-****-****-************",
        "VSwitchId": "vsw-6weq********************"
}
```

CreateVSwitch実行結果の[VSwitchId]の値(vsw-6wep****************の箇所)は他のコマンドで利用する為、控えておきます。

#### 1.5. セキュリティグループの作成および外部からの通信許可設定追加

vSwitchを作成後、CloudShellよりCreateSecurityGroupコマンドを実行して下記構成のセキュリティグループを作成します。

■セキュリティグループ構成
| 項目| 値 | 備考 |
| -- | -- | -- |
| リージョン | ap-northeast-1 | 日本（東京） |
| VPC ID | vpc-6wep**************** | CreateVPC実行結果の[VpcId]の値 |
| 外部からの通信許可 | TCP  0.0.0.0/0 22-22 | 全ての場所からSSH(TCP:22)の通信を許可　|

```bash:CreateSecurityGroupコマンド
aliyun ecs CreateSecurityGroup \
--RegionId ap-northeast-1 \
--VpcId vpc-6wep****************
```
※VpcIdの値(vpc-6wep****************)はCreateVPC実行結果の[VpcId]の値に置き換えてください

```bash:CreateSecurityGroup実行結果
{
        "RequestId": "8F38A6BA-****-****-****-************",
        "SecurityGroupId": "sg-6we3************"
}
```

CreateSecurityGroup実行結果の[SecurityGroupId]の値(sg-6we3************の箇所)は他のコマンドで利用する為、控えておきます。

セキュリティグループ作成後、CloudShellよりAuthorizeSecurityGroupコマンドを実行して外部からの通信許可設定をセキュリティグループへ追加します。

```bash:AuthorizeSecurityGroupコマンド
aliyun ecs AuthorizeSecurityGroup  \
--RegionId ap-northeast-1 \
--SecurityGroupId sg-6we3************ \
--IpProtocol tcp \
--SourceCidrIp 0.0.0.0/0 \
--PortRange 22/22
```
※SecurityGroupIdの値(sg-6we3************)はCreateSecurityGroup実行結果の[SecurityGroupId]の値に置き換えてください

```bash:AuthorizeSecurityGroup実行結果
{
        "RequestId": "71AC45A9-****-****-****-************"
}
```

#### 1.6. ECSインスタンスの作成

VPC、vSwitch、セキュリティグループの作成後、CloudShellよりRunInstancesコマンドを実行して下記構成のECSインスタンスを作成します。

■ECSインスタンス構成
| 項目| 値 | 備考 |
| -- | -- | -- |
| リージョン | ap-northeast-1 | 日本（東京） |
| vSwich ID | vsw-6wep**************** | CreateVSwitch実行結果の[VSwitchId]の値|
| セキュリティグループID | sg-6we3************ | CreateSecurityGroup実行結果の[SecurityGroupId]の値|
| OSイメージ | centos_stream_9_x64_20G_alibase_20221117.vhd | CentOS Stream 9 64bit |
| インスタンスタイプ | ecs.c7.large | 2vCPU/4GiB ($0.096USD/時間) |
| インスタンス名 | serverlessdevs_local | |
| 課金方法 | PostPaid | 従量課金 |
| ピーク帯域幅 | 1Mbps | |
| ストレージ| 20GB(拡張 SSD PL1 )| | 
| パスワード| 任意のパスワードを指定 | rootユーザーのSSHログインパスワード | 


```bash:RunInstancesコマンド
aliyun ecs RunInstances \
--RegionId ap-northeast-1 \
--VSwitchId vsw-6we3************ \
--SecurityGroupId sg-6we3************ \
--ImageId centos_stream_9_x64_20G_alibase_20221117.vhd \
--InstanceType ecs.c7.large \
--InstanceName serverlessdevs_local \
--InstanceChargeType PostPaid \
--InternetMaxBandwidthOut 1 \
--SystemDisk.Category cloud_essd \
--SystemDisk.Size 20 \
--Password <Your password>
```
※VSwitchIdの値(vsw-6we3************)はCreateVSwitch実行結果の[VSwitchId]の値に置き換えてください
※SecurityGroupIdの値(sg-6we3************)はCreateSecurityGroup実行結果の[SecurityGroupId]の値に置き換えてください
※passwordの値(Your passwordの箇所)は任意のパスワードの値に置き換えてください

```bash:RunInstances実行結果
{
        "InstanceIdSets": {
                "InstanceIdSet": [
                        "i-6weh*************"
                ]
        },
        "RequestId": "52BFD70A-****-****-****-************"
}
```

RunInstances実行結果の[InstanceIdSet]の値(i-6weh*************の箇所)は他のコマンドで利用する為、控えておきます。
設定したpasswordの値についても忘れずに控えておいてください。



#### 1.7. ECSインスタンスへの接続確認


ECSインスタンス作成後、CloudShellよりDescribeInstancesコマンドを実行してECSインスタンスのパブリックIPアドレスを確認します。

```bash:DescribeInstancesコマンド
aliyun ecs DescribeInstances \
--RegionId ap-northeast-1 \
--InstanceIds '["i-6weh*************"]' \
| grep -A3 PublicIpAddress
```
※InstanceIdsの値(i-6weh*************)はRunInstances実行結果[InstanceIdSet]の値に置き換えてください

```bash:DescribeInstances実行結果
"PublicIpAddress": {
        "IpAddress": [
                "47.***.***.***"
        ]
```

DescribeInstances実行結果の[IpAddress]の値(47.***.***.***の箇所)はSSH接続コマンドで利用する為、控えておきます。

パブリックIPアドレスの確認後、CloudShellよりECSインスタンスへのSSH接続確認を行います。

```bash:SSH接続コマンド
ssh root@47.***.***.***
```
※接続先IPアドレスの値(47.***)はDescribeInstances実行結果の[IpAddress]の値に置き換えてください

問題なくSSH接続が行うと下記実行結果となります。

```bash:SSH接続実行結果
※初回のみ確認表示あり
The authenticity of host [47.***.***.*** ([47.***.***.***) cant be established.
ECDSA key fingerprint is SHA256:xU1SqX2H***************************************.
Are you sure you want to continue connecting (yes/no)? '<yesを入力>'
Warning: Permanently added 47.[47.***.***.*** (ECDSA) to the list of known hosts.

root@47.[47.***.***.***s password: '<RunInstancesコマンド実行時のパスワードを入力>'

Welcome to Alibaba Cloud Elastic Compute Service !

Activate the web console with: systemctl enable --now cockpit.socket

[root@iZ6w******** ~]# 
```

次にECS管理コンソールからのワークベンチ接続も確認します。ECS管理コンソールへ移動後、今回構築を行ったECSインスタンスを選択します。

![ECS_50010.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/13a4aa35-ffbf-bb75-d8a4-dce6ae09df0d.png)

ECS管理コンソールのインスタンス詳細画面にて【接続】を選択します。

![ECS_50011.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/26b9234a-ee9b-b1d3-c699-36bce136939f.png)

接続とコマンド画面にて「ワークベンチ接続（デフォルト）」の【接続】を選択します。

![ECS_50012.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/27871ff1-fc1c-42db-9841-0d0db34931ae.png)

InstanceLogin画面にてRunInstanceコマンドにて入力したパスワードをPasswordの箇所に入力後、【OK】を選択します。

![ECS_50013.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/93ec6532-0ad5-dd05-6b28-a60084cbd24b.png)

ECS管理コンソールからECSインスタンスへ接続できたことを確認します。

![ECS_50014.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/f3e503f6-a69d-4221-7583-006c38b33e30.png)


接続確認後、しばらく利用しない場合はECSインスタンスを停止しておきましょう。

## ■ Next Time

次回は次の手順の「Javaフレームワークを実装および開発【開発用ECSインスタンス】」を実施します。