AWS EKS を構築して Exastro IT Automationをインストールしてみた（v2.1.0）

# はじめに
Exastro IT Automation (以降ITAと表記）の Version2 版がリリースされたようです。（公式ドキュメントは[<こちら>](https://ita-docs.exastro.org/))

公式ドキュメントではAzure AKS 上へのインストールが前提となっていますが、コンテナベースであれば普段使いしている AWS の EKS にもインストールできるんじゃないかと思い試してみました。

公式ドキュメントでは以下３種類のサービス公開方式について記載されており、Ingress を例として説明が行われていましたが、本記事では比較的簡単に実現できそうな NodePort 方式で試してみます。
* Ingress 
* LoadBalancer
* NodePort



## Exastro IT Automationとは
ITAは、システム設定をIaC(Infrastructure as Code)化して一元管理するためのオープンソースフレームワークです。
ITA では、機器情報、設定値、作業履歴などを管理する「構成管理」機能と、各機器の構築、運用設定などをワークフローとして管理、実行する「連携実行」機能を提供します。各機器の構築、運用設定などは Ansible や Terraform などのPF 構築ツールで行い、ITA ではこれらのツールと連携させるドライバーを提供します。また、これらの機能をブラウザ経由で操作するUI と、運用、保守に必要となるユーザー管理、権限管理などの機能を提供します。

## 想定される対象読者
AWS 上で以下のような基本操作ができる方を対象としています。
* VPCやサブネット、ルートテーブル、セキュリティグループなどのネットワーク環境の構築
* EC2 インスタンスの作成
* IAM Role の作成

## 作業環境
+ ITA 実行環境
    + HW：AWS EKS
    + OS：Amazon Linux2
    + AP：Exastro IT Automation v2.1.0
+ 操作用 EC2 インスタンス (`ITA-WebAccess`)
    + ブラウザ：Google Chrome
    + OS：Windows Server 2022
+ 各種ツール実行用EC2インスタンス (`ITA-CLI-Working`)
    + OS：RHEL8
+ GitLab 実行用 EC2 インスタンス (`ITA-GitLab`)
    + OS：Ubuntu 21.04




## 作業手順
今回、AWS CLI を利用してAWS EKS を構築し、EKS 上にITA v2.1.0をインストールしてみました。具体的な手順は以下の通りです。

1. ネットワーク構成 (VPC、サブネット、ルートテーブル、セキュリティグループの設定など)
2. 各種ツールのインストール
3. GitLab 環境の構築
3. AWS EKS用 IAM Role の作成
3. AWS EKS の構築
3. ITA(v2.1.0)のインストール
3. Organization の作成
3. ワークスペース作成
Appendix
・EKS ワークノードの一時停止・再起動方法
・Stack の削除

### 1. ネットワーク構成
今回ITAのインストールを試した AWS 環境でのネットワーク構成は以下のようになっています。
大まかな構成としては、`踏み台サーバー`を経由して、`ITA-CLI-Working`や`ITA-WebAccess`、`ITA-GitLab`にログインを実行し、設定を行いました。

こちらを事前に準備したうえで、次の手順に進みました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/a17f9f0a-72f3-230f-aebe-882d6ea4fbc4.png)


* 各 EC2 インスタンスの概要一覧

|インスタンス名  |AMI名  |AMI ID  |インスタンスタイプ  |セキュリティグループ  |役割  |
|---|---|---|---|---|---|
|ITA-NAT  |amzn-ami-vpc-nat-2018.03.0.20221018.0-x86_64-ebs  |ami-04475a950b13bd6cd  |t2.micro|ITA-NAT-SG  |NAT機能  |
|ITA-CLI-Working  |RHEL-8.6.0_HVM-20220503-x86_64-2-Hourly2-GP2  |ami-0f903fb156f24adbf  |t2.micro|ITA-NAT-SG   |AWS CLI実行用マシン  |
|ITA-WebAccess  |Windows_Server-2022-English-Full-Base-2023.01.19  |ami-05f53c2def3a51a08  |t2.micro|ITA-NAT-SG、working-win-server   |ITAアクセス用マシン  |
|ITA-GitLab  |ubuntu/images/hvm-ssd/ubuntu-hirsute-21.04-amd64-server-20211028  |ami-03f2380ca7c2b3f1e  |t2.medium|ITA-NAT-SG   |GitLab実行用マシン  |


* 各セキュリティグループ (SG)の設定値一覧

    * ITA-NAT-SG 
        * インバウンドルール

        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |-  |SSH  |TCP  |22  |ITA-NAT-SG  |
        |-  |HTTPS  |TCP  |443  |ITA-NAT-SG  |
        |-  |HTTP  |TCP  |80  |ITA-NAT-SG  |

        * アウトバウンドルール

        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |IPv4 |All traffic  |ALL  |ALL  |0.0.0.0/0  |


    * working-win-server
    
        * インバウンドルール
    
        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |IPv4  |HTTP  |TCP  |80  |0.0.0.0/0  |
        |IPv4  |HTTPS  |TCP  |443  |0.0.0.0/0  |
        |IPv4  |RDP  |TCP  |3389  |[VPC の IP アドレス]  |
    
    
        * アウトバウンドルール
    
        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |IPv4 |ALL traffic  |ALL  |ALL  |0.0.0.0/0  |

    * eks-cluster-sg-[cluster-name]-xxxx **(※EKSクラスター作成時に自動作成されます)**
    
        * インバウンドルール
    
        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |IPv4  |All traffic  |All  |All  |eks-cluster-sg-[cluster-name]-xxxx  |
        |IPv4  |All traffic  |All  |All  |[ITA-WebAccessが属するサブネットのIPアドレス]  |
    
        * アウトバウンドルール
    
        |IPバージョン  |タイプ  |プロトコル  |ポート範囲  |ソース  |
        |---|---|---|---|---|
        |IPv4 |ALL traffic  |ALL  |ALL  |0.0.0.0/0  |



* サブネット
    * パブリックサブネット×1
    * プライベートサブネット×2
        * Name：`ita-eks-master-private-a1`
        * Name：`ita-eks-worker-private-c1`

* ルートテーブル
    * パブリックサブネットのルートテーブル
 
        |送信先  |ターゲット  |   
        |---|---|
        |[VPC の IP アドレス]  |local  |
        |0.0.0.0/0  |インターネットゲートウェイ  |
        
    * `ita-eks-master-private-a1` のルートテーブル
    
        |送信先  |ターゲット  |   
        |---|---|
        |[VPC の IP アドレス]  |local  |
        |0.0.0.0/0  |ITA-NAT  |

    * `ita-eks-worker-private-c1` のルートテーブル

        |送信先  |ターゲット  |   
        |---|---|
        |[VPC の IP アドレス]  |local  |
        |0.0.0.0/0  |ITA-NAT  |



* その他必要要件
    * `ita-eks-worker-private-c1` から NAT インスタンスを介してインターネットに接続できること

### 2. 各種ツールのインストール
[1.ネットワーク構成](https://qiita.com/kojitakatera/private/1abe4ed4d5dff5eebcdc#1-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%A7%8B%E6%88%90)ができたら、`ITA-CLI-Working` に `ec2-user` でログインし、 `AWS CLI` をインストールしました。(実行内容について詳しく知りたい方は[こちら](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)を参照してください。)

```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
```
``` 
sudo yum install unzip
```
``` 
unzip awscliv2.zip
```
``` 
sudo ./aws/install
```
以下のコマンドでインストールが正常に行われているかを確認しました。
``` 
aws --version
```

```text:出力例
aws-cli/2.11.4 Python/3.11.2 Linux/4.18.0-372.9.1.el8.x86_64 exe/x86_64.rhel.8 prompt/off
```

続いて、同じく`ITA-CLI-Working` に `kubectl` をインストールしました。(実行内容について詳しく知りたい方は[こちら](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)を参照してください。)

``` 
curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.23.7/2022-06-29/bin/linux/amd64/kubectl
```
``` 
chmod +x ./kubectl
```
``` 
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
```
以下のコマンドでインストールが正常に行われているかを確認しました。
``` 
kubectl version --short --client
```
```text:出力例
Client Version: v1.23.7-eks-4721010
```

同じく`ITA-CLI-Working` に `helm` をインストールしました。(実行内容について詳しく知りたい方は[こちら](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/helm.html)を参照してください。)
``` 
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh 
```
``` 
chmod 700 get_helm.sh 
```
``` 
sudo yum install openssl
```
``` 
./get_helm.sh
```
以下のコマンドでインストールが正常に行われているかを確認しました。
``` 
helm version --short | cut -d + -f 1
```
```text:出力例
v3.11.2
```

最後に 任意の名前でIAM Roleを作成し、`ITA-CLI-Working` にアタッチしました。

``` json:IAM Role の信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "ec2.amazonaws.com",
                    "eks.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

``` json:IAM Role にアタッチした IAM ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "eks:*",
                "autoscaling:AttachInstances",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeAutoScalingInstances",
                "autoscaling:DetachInstances",
                "cloudformation:CreateStack",
                "cloudformation:CreateUploadBucket",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStacks",
                "cloudformation:GetTemplateSummary",
                "cloudformation:ListStacks",
                "ec2:CreateLaunchTemplate",
                "ec2:CreateLaunchTemplateVersion",
                "ec2:DeleteLaunchTemplate",
                "ec2:DescribeElasticGpus",
                "ec2:DescribeInstanceAttribute",
                "ec2:DescribeInstanceCreditSpecifications",
                "ec2:DescribeLaunchTemplateVersions",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSpotInstanceRequests",
                "ec2:DescribeSubnets",
                "ec2:DescribeVolumes",
                "ec2:DescribeVpcs",
                "ec2:GetLaunchTemplateData",
                "ec2:RunInstances",
                "ec2:StartInstances",
                "ec2:StopInstances",
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:CreateServiceLinkedRole",
                "iam:DeletePolicy",
                "iam:DeleteRole",
                "iam:DetachRolePolicy",
                "iam:GetPolicy",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:PassRole",
                "s3:CreateBucket",
                "s3:GetObject",
                "s3:PutObject",
                "sts:DecodeAuthorizationMessage"
            ],
            "Resource": "*"
        }
    ]
}
```



### 3. GitLab 環境の構築
`ITA-GitLab` に `ubuntu` でログインし、 `GitLab` をインストールしました。

まずは、以下のコマンドで依存パッケージをインストールしました。
``` 
sudo apt update
```
``` 
sudo apt-get install curl openssh-server ca-certificates postfix 
```

続いて、GitLabをインストールしました。
``` 
wget --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/ubuntu/bionic/gitlab-ce_15.4.3-ce.0_amd64.deb/download.deb
```
``` 
sudo dpkg -i gitlab-ce_15.4.3-ce.0_amd64.deb
```

次に、ブラウザでアクセスする際の IP アドレスを `external_url`に指定しました。
``` 
sudo vim /etc/gitlab/gitlab.rb
```

上記コマンドを入力した後、`external_url`と書かれている箇所を探し、以下のように変更しました。
``` 
external_url 'http://[ITA-GitLab のIPアドレス]'
```

以下のコマンドで GitLab の再起動を実行しました。

``` 
sudo gitlab-ctl reconfigure
```
以下のコマンドで GitLab の自動起動設定を有効化しました。 
``` 
sudo systemctl enable gitlab-runsvdir.service
```
今回は GitLab にログインする際に root の初期パスワードを使用したため、
以下のコマンドで root の初期パスワードを確認しました。確認したパスワードはメモなどに控えておきました。
``` 
sudo cat /etc/gitlab/initial_root_password
```

:::note warn
参照した`initial_root_password`というファイルは24時間で消えてしまい、パスワードが確認できなくなってしまうのでメモなどに控えておくと良いと思います。
:::



最後に ITA v2.1.0 インストール時に使用する `GITLAB_ROOT_TOKEN`の取得を行いました。
まずは、`ITA-WebAccess`に対してRDP接続を行い、ブラウザを起動させて`ITA-GitLab`に対して`http://[ITA-GitLab の IP アドレス]`でアクセスしました。

ログイン画面では以下を入力しました。
* ユーザー名：root
* パスワード：(先ほど確認したrootの初期パスワード)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/ac2d9c72-f598-8c80-5c96-5aa75a762bf3.png)



右上のアカウントアイコンをクリックし、表示されたメニューの中から「Preferences」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/01f47737-11a2-f75c-b000-715b609111a1.png)


続いて、左のメニューから「Access Tokens」タブを選択して、Access Tokenの設定を行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/fd2d19ea-4f92-e0ed-dc39-50ebecf65eca.png)


以下の設定箇所について設定を行いました。

* `Token name`：トークン名
* `Expiration date`：トークンの有効期限 (デフォルトは30日)
* `Select scopes`：トークンで実行できるアクションのスコープを指定します。ここでは`api`、`write_repository`、`sudo`を選択しました。

最後に`Create personal access token`をクリックし、トークンを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/0bb4c803-66b5-1e8c-adc6-f87a239c94d8.png)

ITA v2.1.0 インストール時に`GITLAB_ROOT_TOKEN`として使用するため、ここで作成したトークンをコピーし、メモなどに控えておきました。


### 4. AWS EKS用 IAM Role の作成
続いて、クラスターの IAM Role、及びノードの IAM Role を作成しました。
構築時に以下の情報の入力を行いました。
* [EKS-Cluster-Role]：作成するクラスターの IAM Role の名前 (任意)
* [EKS-Node-Role]：作成するノードの IAM Role の名前 (任意)



`ITA-CLI-Working`に`ec2-user`でログイン後、以下のような`eks-cluster-role-trust-policy.json`ファイルを作成しました。

```json:eks-cluster-role-trust-policy.json
{
    "Version":"2012-10-17",
    "Statement":[
        {
            "Effect":"Allow",
            "Principal":{
                "Service":"eks.amazonaws.com"
            },
            "Action":"sts:AssumeRole"
        }
    ]
}
```
続いて、`eks-cluster-role-trust-policy.json`で指定した信頼ポリシーに関する内容でクラスター用の IAM Role を作成しました。

```
aws iam create-role --role-name [EKS-Cluster-Role] --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
```
次に、作成したクラスタ用の IAM Role に必要なIAM ポリシーをアタッチしました。

```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name [EKS-Cluster-Role]
```
```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSServicePolicy --role-name [EKS-Cluster-Role]
```

今度は以下のような`node-role-trust-policy.json`ファイルを作成しました。

```json:node-role-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
`node-role-trust-policy.json`で指定した信頼ポリシーに関する内容でノード用の IAM Role を作成しました。
```
aws iam create-role --role-name [EKS-Node-Role] --assume-role-policy-document file://"node-role-trust-policy.json"
```
作成したノード用の IAM Role に必要なIAM ポリシーをアタッチしました。
```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy --role-name [EKS-Node-Role]
```


```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name [EKS-Node-Role]
```
最後にノード用の IAM Role に CNI の IAM ポリシーをアタッチしました。

```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy --role-name [EKS-Node-Role]
```

### 5. AWS EKS の構築
構築時に以下の情報の入力を行いました。
* [cluster-name]：構築する EKS クラスターの名前 (任意)
* [region-code]：EKS クラスターを構築するリージョン
    * 今回は`ap-northeast-1`を指定しました。
* [AwsAccoutId]：AWS アカウント ID
* subnetIds：EKS クラスターを配置するサブネットの id
    * 今回は`ita-eks-master-private-a1`、`ita-eks-worker-private-c1`を指定しました。
* securityGroupIds：EKS クラスターに付与する SG の id
    * 今回は`ITA-NAT-SG`を指定しました。
* [template-name]：起動テンプレートの名前 (任意)
* [nodegroup-name]：ノードグループの名前 (任意)

`ITA-CLI-Working`に`ec2-user`でログイン後、以下のコマンドを実行し、EKS クラスターを作成しました。
```
aws eks create-cluster --region [region-code] --name [cluster-name] --kubernetes-version 1.23 \
   --role-arn arn:aws:iam::[AwsAccoutId]:role/[EKS-Cluster-Role] \
   --resources-vpc-config subnetIds=[ita-eks-master-private-a1 の id],[ita-eks-worker-private-c1 の id],securityGroupIds=[ITA-NAT-SG のid],endpointPublicAccess=false,endpointPrivateAccess=true
```
クラスターがプロビジョニングされるまでに数分かかりました。以下のコマンドでクラスターのステータスのクエリを実行し、`"ACTIVE"`と表示されるまで待ちました。

```
aws eks describe-cluster --region [region-code] --name [cluster-name] --query "cluster.status"
```
また、この時点でEKS クラスターに対して`eks-cluster-sg-[cluster-name]-xxxx`という SG が自動で作成されているのを確認しました。[1. ネットワーク構成](https://qiita.com/kojitakatera/private/1abe4ed4d5dff5eebcdc#1-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%A7%8B%E6%88%90)の`eks-cluster-sg-[cluster-name]-xxxx`のインバウンドルールのように設定を行いました。


以下のコマンドを実行し、新しいコンテキストを kubectl config ファイルに追加して、kubectl がクラスターと通信できるようにしました。

```
aws eks update-kubeconfig --region [region-code] --name [cluster-name]
```

起動テンプレートの設定ファイルとして以下のような`ec2-launch-template.json`を作成しました。
ITA インストールの際にインターネット接続が必要となるため、`eks-cluster-sg-[cluster-name]-xxxx`に加え、 今回は`ITA-NAT-SG`を指定しました。

```json:ec2-launch-template.json
{
     "SecurityGroupIds": ["ITA-NAT-SG のid", "eks-cluster-sg-[cluster-name]-xxxx の id"]
}
```
以下のコマンドを実行し、起動テンプレートを作成しました。
```
aws ec2 create-launch-template \
  --launch-template-name [template-name] \
  --launch-template-data file://"ec2-launch-template.json"
```
続いて、以下のコマンドを実行し、ノードグループを作成しました。( ITA インストール用のEC2インスタンスタイプは `t3.large`以上が良いと思います。)
```
aws eks create-nodegroup --cluster-name [cluster-name] \
        --nodegroup-name [nodegroup-name] \
        --subnets [ita-eks-master-private-a1 の id] \
        --node-role 'arn:aws:iam::[AwsAccoutId]:role/[EKS-Node-Role]' \
        --launch-template name=[template-name],version=1 \
        --ami-type AL2_x86_64 \
        --instance-types t3.large \
        --scaling-config minSize=0,maxSize=1,desiredSize=1
```
クラスターがプロビジョニングされるまでに数分かかりました。以下のコマンドを実行し、`"status": "ACTIVE"`となるまで待ちました。

```
aws eks describe-nodegroup --cluster-name [cluster-name] --nodegroup-name [nodegroup-name]
```




:::note info 
**Note**
Cloudformation テンプレートを使用することで「4. AWS EKS用 IAM Role の作成」及び「5. AWS EKS の構築」の手順を自動化してみました。今回行った手順を以下に示します。

**Stack の作成**

(1) `ITA-CLI-Working`に`ec2-user`でログインし、`ITA-Cluster-stack.yaml`ファイルを作成しました。
<details>
<summary>ITA-Cluster-stack.yaml</summary>

```yaml:ITA-Cluster-stack.yaml
Parameters:
  ClusterIAMRoleName:
    Type: String
#    Default:
    Description: Cluster IAM Role Name
  NodeIAMRoleName:
    Type: String
#    Default:
    Description: Node IAM Role Name
  clusterName:
    Type: String
#    Default:
    Description: cluster Name
  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
#    Default:
    Description: Security groups that can be used to access the EC2 instances
    ConstraintDescription: must be list of EC2 security group ids
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
#    Default:
    Description: Security Subnet that can be used to access the EC2 instances
    ConstraintDescription: must be list of EC2 Subnet ids
  LaunchTemplateName:
    Type: String
#    Default:
    Description: Launch Template Name
  NodegroupName:
    Type: String
#    Default:
    Description: Node group Name
  NodeSubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
#    Default:
    Description: Security Subnet that can be used to access the EC2 instances
    ConstraintDescription: must be list of EC2 Subnet ids
Resources:
# Create Cluster IAM role
  ClusterIAMRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - Effect: "Allow"
            Principal: 
              Service: 
                - "eks.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy
      RoleName:
        Ref: ClusterIAMRoleName
# Create Node IAM role
  NodeIAMRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - Effect: "Allow"
            Principal: 
              Service: 
                - "ec2.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
      RoleName:
        Ref: NodeIAMRoleName
# Create Cluster
  EKSCluster:
    Type: AWS::EKS::Cluster
    Properties: 
      Name:
        Ref: clusterName
      ResourcesVpcConfig:
        EndpointPrivateAccess: true
        EndpointPublicAccess: false
        SecurityGroupIds:
          Ref: SecurityGroupIds
        SubnetIds:
          Ref: SubnetIds
      RoleArn: !GetAtt ClusterIAMRole.Arn
      Version: 1.23
# Create template
  MyLaunchTemplate:
      Type: AWS::EC2::LaunchTemplate
      Properties:
        LaunchTemplateName:
          Ref: LaunchTemplateName
        LaunchTemplateData:
          SecurityGroupIds: !Split
            - ","
            - !Sub
              - "${existingSgToString},${EKSCluster.ClusterSecurityGroupId}"
              - existingSgToString: !Join [",",!Ref "SecurityGroupIds"]
# Create Nodegroup
  EKSNodegroup:
    Type: AWS::EKS::Nodegroup
    Properties:
      AmiType: AL2_x86_64
      ClusterName: !Ref EKSCluster
      InstanceTypes:
        - t3.large
      LaunchTemplate:
        Id: !Ref MyLaunchTemplate
        Version: 1
      NodegroupName:
        Ref: NodegroupName
      NodeRole: !GetAtt NodeIAMRole.Arn
      ScalingConfig:
        MinSize: 0
        DesiredSize: 1
        MaxSize: 1
      Subnets:
        Ref: NodeSubnetIds
```
</details>

(2) 下記のコマンドを実行しました。

[stack-name]：作成する stack の名前 (任意)
```
aws cloudformation create-stack --stack-name [stack-name] --template-body file://ITA-Cluster-stack.yaml --parameters \
  ParameterKey=ClusterIAMRoleName,ParameterValue=[EKS-Cluster-Role] \
  ParameterKey=NodeIAMRoleName,ParameterValue=[EKS-Node-Role] \
  ParameterKey=clusterName,ParameterValue=[cluster-name] \
  ParameterKey=SecurityGroupIds,ParameterValue=[ITA-NAT-SG のid]  \
  ParameterKey=SubnetIds,ParameterValue=[ita-eks-master-private-a1 の id]\\,[ita-eks-worker-private-c1 の id] \
  ParameterKey=LaunchTemplateName,ParameterValue=[template-name] \
  ParameterKey=NodegroupName,ParameterValue=[nodegroup-name] \
  ParameterKey=NodeSubnetIds,ParameterValue=[ita-eks-master-private-a1 の id] --capabilities CAPABILITY_NAMED_IAM
```

(3) 以下のコマンドで実行結果を確認し、`"StackStatus": "CREATE_COMPLETE"`となるまで待ちました。

```
aws cloudformation list-stacks
```

構築失敗の場合、以下のコマンドで各`StackEvent`の`ResourceStatus`の状態を確認しました。
```
aws cloudformation describe-stack-events --stack-name [stack-name]
```


(4) 以下のコマンドを実行し、新しいコンテキストを `kubectl config` ファイルに追加して、kubectl がクラスターと通信できるようにしました。

```
aws eks update-kubeconfig --region [region-code] --name [cluster-name]
```


:::

### 6. ITA(v2.1.0)のインストール
土台となる EKS 構築は完了し、ここからは公式ドキュメントに沿って ITA v2.1.0 のインストールを進めていきました。コマンド実行は`ITA-CLI-Working`に`ec2-user`でログインして実行しました。


https://ita-docs.exastro.org/2.0/ja/installation/helm_on_kubernetes.html

手順の中で、複数の選択肢から一つを選択する項目があったため、今回はそれぞれ以下を選択してインストールを実行しました。

* 1.3.3. サービス公開の設定：NodePort
* 1.3.4. データベース連携：データベースコンテナ、hostPath利用
* 1.3.8. 永続ボリュームの設定：Kubernetes ノードのディレクトリ
* 1.4.2. インストール：NordPort




今回作成した`exastro.yaml`、`pv-database.yaml`、`pv-ita-common.yaml`はそれぞれ以下の通りです。

<details>
<summary>exastro.yaml</summary>

```yaml:exastro.yaml
# Default values for Exastro.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
  itaGlobalDefinition:
    name: ita-global
    enabled: true
    image:
      registry: "docker.io"
      organization: exastro
      package: exastro-it-automation
    config:
      DEFAULT_LANGUAGE: "ja"
      LANGUAGE: "en"
      CONTAINER_BASE: "kubernetes"
      TZ: "Asia/Tokyo"
      STORAGEPATH: "/storage/"
    secret:
      ENCRYPT_KEY: ""
    persistence:
      enabled: true
      accessMode: ReadWriteMany
      size: 10Gi
      volumeType: hostPath # e.g.) hostPath or AKS
      storageClass: "-" # e.g.) azurefile or - (None)
      # matchLabels:
      #   release: "stable"
      # matchExpressions:
      #   - {key: environment, operator: In, values: [dev]}
  gitlabDefinition:
    name: gitlab
    enabled: true
    config:
      GITLAB_PROTOCOL: "http"
      GITLAB_HOST: "[ITA-GitLab の IP アドレス]"
      GITLAB_PORT: "80"
    secret:
      GITLAB_ROOT_TOKEN: "[作成した GITLAB_ROOT_TOKEN]"
  itaDatabaseDefinition:
    name: ita-database
    enabled: true
    config:
      DB_VENDOR: "mariadb"
      DB_HOST: "mariadb"
      DB_PORT: "3306"
      DB_DATABASE: "ITA_DB"
    secret:
      DB_ADMIN_USER: "root"
      DB_ADMIN_PASSWORD: "[データベースコンテナの root のパスワード]"
      DB_USER: "[Exastro IT Automation のアプリが使うDBユーザ]"
      DB_PASSWORD: "[Exastro IT Automation のアプリが使うDBユーザのパスワード]"
  pfGlobalDefinition:
    name: pf-global
    enabled: true
    image:
      registry: "docker.io"
      organization: exastro
      package: exastro-platform
    config:
      DEFAULT_LANGUAGE: "ja"
      LANGUAGE: "en"
      TZ: "Asia/Tokyo"
      PYTHONIOENCODING: utf-8
      PLATFORM_API_PROTOCOL: "http"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
      PLATFORM_WEB_PROTOCOL: "http"
      PLATFORM_WEB_HOST: "platform-web"
      PLATFORM_WEB_PORT: "8000"
    secret:
      ENCRYPT_KEY: ""
    persistence:
      enabled: true
      accessMode: ReadWriteMany
      size: 10Gi
      volumeType: hostPath # e.g.) hostPath or AKS
      storageClass: "-" # e.g.) azurefile or - (None)
      # matchLabels:
      #   release: "stable"
      # matchExpressions:
      #   - {key: environment, operator: In, values: [dev]}
  keycloakDefinition:
    name: keycloak
    enabled: true
    config:
      API_KEYCLOAK_PROTOCOL: "http"
      API_KEYCLOAK_HOST: "keycloak"
      API_KEYCLOAK_PORT: "8080"
      KEYCLOAK_PROTOCOL: "http"
      KEYCLOAK_HOST: "keycloak"
      KEYCLOAK_PORT: "8080"
      KEYCLOAK_MASTER_REALM: "master"
      KEYCLOAK_DB_DATABASE: "keycloak"
    secret:
      KEYCLOAK_USER: "[Exastro システムの管理者]"
      KEYCLOAK_PASSWORD: "[Exastro システムの管理者のパスワード]"
      KEYCLOAK_DB_USER: "[Keycloak が使うDBユーザ]"
      KEYCLOAK_DB_PASSWORD: "[Keycloak が使うDBユーザのパスワード]"
  itaDefinition:
    name: ita
    enabled: true
    config:
      ITA_WEB_PROTOCOL: "http"
      ITA_WEB_HOST: "ita-web-server"
      ITA_WEB_PORT: "8000"
      ITA_API_PROTOCOL: "http"
      ITA_API_HOST: "ita-api-organization"
      ITA_API_PORT: "8080"
      ITA_API_ADMIN_PROTOCOL: "http"
      ITA_API_ADMIN_HOST: "ita-api-admin"
      ITA_API_ADMIN_PORT: "8080"
  pfDatabaseDefinition:
    name: pf-database
    enabled: true
    config:
      DB_VENDOR: "mariadb"
      DB_HOST: "mariadb"
      DB_PORT: "3306"
      DB_DATABASE: "platform"
    secret:
      DB_ADMIN_USER: "root"
      DB_ADMIN_PASSWORD: "[データベースコンテナの root のパスワード]"
      DB_USER: "[Exastro 共通基盤が使うDBユーザ]"
      DB_PASSWORD: "[Exastro 共通基盤が使うDBユーザのパスワード]"
  databaseDefinition:
    name: mariadb
    enabled: true
    secret:
      MARIADB_ROOT_PASSWORD: "[データベースコンテナの root のパスワード]"
    persistence:
      enabled: true
      reinstall: false
      accessMode: ReadWriteOnce
      size: 20Gi
      volumeType: hostPath
      storageClass: "-"
      # matchLabels:
      #   release: "stable"
      # matchExpressions:
      #   - {key: environment, operator: In, values: [dev]}

exastro-it-automation:
  ita-api-admin:
    replicaCount: 1
    image:
      repository: "exastro/exastro-it-automation-api-admin"
      tag: ""
      pullPolicy: IfNotPresent
    extraEnv:
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"

  ita-api-organization:
    replicaCount: 1
    image:
      repository: "exastro/exastro-it-automation-api-organization"
      tag: ""
      pullPolicy: IfNotPresent
    extraEnv:
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"

  ita-by-ansible-execute:
    replicaCount: 1
    image:
      repository: "exastro/exastro-it-automation-by-ansible-execute"
      tag: ""
      pullPolicy: IfNotPresent
    extraEnv:
      EXECUTE_INTERVAL: "10"
      ANSIBLE_AGENT_IMAGE: "exastro/exastro-it-automation-by-ansible-agent"
      ANSIBLE_AGENT_IMAGE_TAG: ""
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    serviceAccount:
      create: false
      name: "ita-by-ansible-execute-sa"

  ita-by-ansible-legacy-role-vars-listup:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-ansible-legacy-role-vars-listup"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-ansible-legacy-vars-listup:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-ansible-legacy-vars-listup"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-ansible-pioneer-vars-listup:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-ansible-pioneer-vars-listup"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-ansible-towermaster-sync:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-ansible-towermaster-sync"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-cicd-for-iac:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-cicd-for-iac"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-collector:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-collector"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-conductor-regularly:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-conductor-regularly"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-conductor-synchronize:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-conductor-synchronize"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-excel-export-import:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-excel-export-import"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-execinstance-dataautoclean:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-execinstance-dataautoclean"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-file-autoclean:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-file-autoclean"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-hostgroup-split:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-hostgroup-split"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-menu-create:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-menu-create"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-menu-export-import:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-menu-export-import"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-terraform-cli-execute:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-terraform-cli-execute"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-terraform-cli-vars-listup:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-terraform-cli-vars-listup"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-terraform-cloud-ep-execute:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-terraform-cloud-ep-execute"
      tag: ""
      pullPolicy: IfNotPresent

  ita-by-terraform-cloud-ep-vars-listup:
    replicaCount: 1
    extraEnv:
      EXECUTE_INTERVAL: "10"
      PLATFORM_API_HOST: "platform-api"
      PLATFORM_API_PORT: "8000"
    image:
      repository: "exastro/exastro-it-automation-by-terraform-cloud-ep-vars-listup"
      tag: ""
      pullPolicy: IfNotPresent

  ita-database-setup-job:
    image:
      repository: ""
      tag: ""
      pullPolicy: IfNotPresent

  ita-web-server:
    replicaCount: 1
    image:
      repository: "exastro/exastro-it-automation-web-server"
      tag: ""
      pullPolicy: IfNotPresent

exastro-platform:
  platform-api:
    image:
      repository: "exastro/exastro-platform-api"
      tag: ""

  platform-auth:
    extraEnv:
      # Please set the URL to access
      EXTERNAL_URL: ""
      EXTERNAL_URL_MNG: ""
    ingress:
      enabled: false
      hosts:
        - host: exastro-suite.example.local
          paths:
            - path: /
              pathType: Prefix
              backend: "http"
        - host: exastro-suite-mng.example.local
          paths:
            - path: /
              pathType: Prefix
              backend: "httpMng"
    service:
      type: NodePort
      http:
        nodePort: 30080
      httpMng:
        nodePort: 30081
    image:
      repository: "exastro/exastro-platform-auth"
      tag: ""

  platform-migration:
    image:
      repository: "exastro/exastro-platform-migration"
      tag: ""

  platform-web:
    image:
      repository: "exastro/exastro-platform-web"
      tag: ""

  mariadb:
    enabled: true
    image:
      repository: "mariadb"
      tag: "10.9"
      pullPolicy: IfNotPresent
    resources:
      requests:
        memory: "256Mi"
        cpu: "1m"
      limits:
        memory: "2Gi"
        cpu: "4"

  keycloak:
    enabled: true
    image:
      repository: "exastro/keycloak"
      tag: ""
      pullPolicy: IfNotPresent
    resources:
      requests:
        memory: "256Mi"
        cpu: "1m"
      limits:
        memory: "2Gi"
        cpu: "4"
```
</details>


<details>
<summary>pv-database.yaml</summary>

```yaml:pv-database.yaml
# pv-database.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-database
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /var/data/exastro-suite/exastro-platform/database
    type: DirectoryOrCreate
```
</details>


<details>
<summary>pv-ita-common.yaml</summary>

```yaml:pv-ita-common.yaml
# pv-ita-common.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-ita-common
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /var/data/exastro-suite/exastro-it-automation/ita-common
    type: DirectoryOrCreate
```
</details>


### 7. Organization の作成

Organization作成では`git`と`jq`が必要なようでしたので、以下のコマンドをそれぞれ実行し、インストールしました。

```
sudo yum install git
```
以下のコマンドでインストールが正常に行われているかを確認しました。
```
git --version
```
```text:出力例
git version 2.31.1
```

```
sudo yum install jq
```
以下のコマンドでインストールが正常に行われているかを確認しました。
```
jq --version
```
```text:出力例
jq-1.6
```

Organizationの作成も公式ドキュメントに沿って進めました。**(※今回は一部公式ドキュメントと異なる設定を行いました。)** コマンド実行は`ITA-CLI-Working`に`ec2-user`でログインして実行しました。


https://ita-docs.exastro.org/2.0/ja/manuals/platform_management/organization.html

手順の中で、複数の選択肢から一つを選択する項目については、以下を選択しました。

* 1.3.3. オーガナイゼーション作成：設定ファイルとスクリプトによる作成

:::note warn
**(※一部公式ドキュメントと異なる設定について)**
* `api-auth.conf`は以下のように設定しました。
```text:api-auth.conf
CONF_BASE_URL=http://[Administrator Console の IPアドレス]:[Administrator Console のポート番号]
CURL_OPT=-sv
```
(注) [Administrator Console の IPアドレス]や[Administrator Console のポート番号] は公式ドキュメント「1.4.2 インストール」にある出力結果を使用しました。

* `create-organization.json`は以下のように設定しました。

<details>
<summary>create-organization.json</summary>

```json:create-organization.json
{
    "id"    :   "org001",
    "name"  :   "org001-name",
    "organization_managers" : [
        {
            "username"  :   "admin",
            "email"     :   "admin@example.com",
            "firstName" :   "admin",
            "lastName"  :   "admin",
            "credentials"   :   [
                {
                    "type"      :   "password",
                    "value"     :   "password",
                    "temporary" :   true
                }
            ],
            "requiredActions": [
                "UPDATE_PROFILE"
            ],
            "enabled": true
        }
    ],
    "plan": {},
    "options": {}
}
```
</details>

* オーガナイゼーションへのアクセスは`ITA-WebAccess`上でブラウザ(今回はGoogle Chrome)を起動し、以下の URL を入力しました。
```text:
http://[Exastro Platform の Service Consle の IP アドレス]:[Service Console のポート番号]/[オーガナイゼーションID]/platform/
```
(注1) [Exastro Platform の Service Consle の IP アドレス] や [Service Console のポート番号] は公式ドキュメント「1.4.2 インストール」にある出力結果を使用しました。

(注2) [オーガナイゼーションID] は `create-organization.json`の`id`で指定した値を使用しました。
:::

### 8. ワークスペース作成
まずはログイン確認を行いました。
ログイン画面では、`create-organization.json`で指定したユーザー名とパスワードを入力しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/e371fd33-0243-a473-8dc6-28961c21083c.png)


ログイン出来たらパスワードの更新を求められ、新しいパスワードを入力し、再度ログインを実行しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/dea3410d-994d-5565-4871-f4227afef151.png)


次にアカウント情報の更新を行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/fb70646e-4ade-86f5-10ac-9a42ce111ff2.png)


すると、ITA v2.1.0 の画面が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/0a8c07fe-d96d-c699-b0a7-afdcbbab71c7.png)


作成ボタンをクリックすると、新規ワークスペースの作成画面に遷移しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/d2840234-f38b-5db3-17bf-eeac898863a2.png)

新規ワークスペース作成画面で、ワークスペースIDとワークスペース名を入力し、登録ボタンをクリックしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/4c8e3040-477f-5bc9-7803-2708a3ab60fc.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/f1d34906-419b-4831-ec0e-cac1aa1da7d8.png)

ワークスペースを作成しましたと表示され、閉じるをクリックしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/2c9dacea-4827-3f34-f8a0-3f1abf1c1c19.png)

ワークスペース一覧では、作成したワークスペースが表示されていました。次にITAのロゴをクリックしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/40a578b3-b104-4802-e38a-789903a7ede9.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/346c7f89-ac19-33e4-9848-7289195f57c4.png)

すると、ITAのメインメニューが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926433/9d4417c7-c0ab-d428-fa70-89978ca7805e.png)


### Appendix

**EKS ワークノードの一時停止・再起動方法**

短期的にITA を使わない時に登録済みのデータを保留しながら、 EKS による課金を低減したいと思い、ワークノードを停止する方法を実行しました。
`ITA-CLI-Working`に`ec2-user`でログインし、以下のコマンドを順番に実行しました。

* 一時停止
```
autoScalingGroupName=$(aws eks describe-nodegroup \
     --cluster-name [cluster-name] --nodegroup-name [nodegroup-name] \
     --query "nodegroup.resources.autoScalingGroups[0].name" \
     --output text)
```

```
ec2InstanceId=$(aws autoscaling describe-auto-scaling-groups \
     --auto-scaling-group-names $autoScalingGroupName \
     --query "AutoScalingGroups[0].Instances[0].InstanceId" \
     --output text)
```
以下のコマンドで、ワークノードを AutoScalingGroup からデタッチしました。

```
aws autoscaling detach-instances --instance-ids $ec2InstanceId \
  --auto-scaling-group-name $autoScalingGroupName --should-decrement-desired-capacity
```
以下のコマンドで、ワークノードを停止しました。

```
aws ec2 stop-instances --instance-ids $ec2InstanceId
```

* 再起動

以下のコマンドで、ワークノードを起動しました。

```
aws ec2 start-instances --instance-ids $ec2InstanceId
```
以下のコマンドで、ワークノードを AutoScalingGroup にアタッチしました。
```
aws autoscaling attach-instances \
 --auto-scaling-group-name $autoScalingGroupName --instance-ids $ec2InstanceId
```


**Stack の削除**
Cloudformation テンプレートを使用した際、Stackの削除は以下の手順で行いました。


(1) 作成したスタックを削除する際に、以下のコマンドを実行しました。

```
aws cloudformation delete-stack --stack-name [stack-name]
```

(2) 以下のコマンドで実行結果を確認し、`"StackStatus": "DELETE_COMPLETE"`となるまで待ちました。

```
aws cloudformation list-stacks
```

削除失敗の場合、以下のコマンドで各`StackEvent`の`ResourceStatus`の状態を確認します。
```
aws cloudformation describe-stack-events --stack-name [stack-name]
```


# まとめ
今回は、ITA v2.1.0のインストールと動作確認を行いました。
[公式ドキュメント](https://ita-docs.exastro.org/)では Azure AKS 上へのインストールを前提とし、Ingress や LoadBalancer を使ってサービス公開を行う方法についても記載されています。Azure を使ってインストールを試したい方や今回行ったNode Port以外の方法でサービスを公開したい方は是非そちらを参照してください。