AWS Service Catalogを試してみた

# はじめに
ソリューションアーキテクトプロフェッショナルの勉強をしていて、たびたび出てくるService Catalogが気になったので、公式のチュートリアルをなぞってみました。

# 参考

https://zenn.dev/mn87/articles/81479d5323766c

https://dev.classmethod.jp/articles/summary-of-the-constraints-available-in-the-service-catalog/

https://docs.aws.amazon.com/ja_jp/servicecatalog/latest/adminguide/security-iam-awsmanpol.html

# 仕組み
自分の理解を図示すると、以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/fda97411-3ecc-ad18-f6fd-a443973cbc48.png)

- ポートフォリオ
    - 製品集
    - 利用の権限を、ユーザに付与する
- 製品
    - 作成するリソース
    - CloudFormationなどで設定する

# 料金

以前はポートフォリオに固定料金がかかっていたようですが、現在はコール数だけでの料金になったようです。

https://aws.amazon.com/jp/servicecatalog/pricing/

# やってみた

以下の公式をなぞっていきます。

https://docs.aws.amazon.com/ja_jp/servicecatalog/latest/adminguide/getstarted.html

## ステップ 1: AWS CloudFormation テンプレートのダウンロード

多分しなくてよいです。後ほど、S3バケットのURLを直接指定しています。

## ステップ 2: キーペアを作成する
今回はEC2を作る製品になりますので、キーペアを作成します。EC2のコンソールからつくりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/afc811cf-6ff5-9512-0b31-1020ab4a35c6.png)
.pemで作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c90caad2-003a-0bbc-0adb-b3e22cfd9332.png)
ダウンロードされるので、覚えておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/5adf7151-1914-5b65-66f5-87674bfc5b17.png)

## ステップ 3: Service Catalog ポートフォリオを作成する
コンソールから作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/721f3ba1-ccf0-e7f4-5116-021f89870856.png)
公式のステップの通りに入力して作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/b6219200-88ca-5501-d661-4dd800fe1be4.png)


## ステップ 4: Service Catalog 製品の作成
作成されたポートフォリオの画面から製品を作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e7af7520-eb66-712d-3ca7-0a990477df79.png)

公式の説明の通りの文字列を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/f40a42c0-6ec3-fc97-6550-52595b9b0a54.png)
ここでCloudFormationのファイルをURLから指定します。そのため、最初のダウンロードは不要でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/90bb4fa7-945f-4866-c5c7-5b99299d487d.png)

サポートも入れておきましたけれども、オプションだから不要だったかもしれません。
最後に　製品を作成、をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/cd4ed2f5-5d4e-e495-08b1-cee8f1dd0e5b.png)


ポートフォリオの製品タブを更新すると、出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/7ceaecab-db3f-dadd-5ece-4566e46be119.png)

## ステップ 5: テンプレート制約を追加してインスタンスサイズを制限する
「指定できるインスタンスタイプを"t2.micro", "t2.small"にする」という制約を追加します。
公式の通りにすれば問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8035e6ae-1ec9-9fca-d920-b159912f1e4c.png)
制約にはいろいろな種類がありますが、今回はテンプレートの指定になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/aaade15e-2ff0-202d-8298-65a07a729dc1.png)
制約の定義も、公式の操作をなぞります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/657fb514-57b1-da1c-e780-aa351468d948.png)
説明も張り付けて、作成をクリックします。制約のタブに追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1de1f644-4b47-3c06-0ac9-02b0968fd214.png)

## ステップ 6: IAM ロールを割り当てる起動制約を追加する & ユーザも作成
ここで以下を作成します。
- IAMロール
    - Service Catalogが、製品を起動するときに使う
付与するポリシーは公式のを使っています。

また同じCloudFormation内で以下も作成しています。
- IAMユーザ
    - この製品を使うためのユーザ
    - Service Catalogのコンソールを使うため、`AWSServiceCatalogEndUserFullAccess`を付与
    - 製品に使うCFnテンプレートをS3から落とすため、S3へのGetObjectを付与
    - 上記のロールは紐づけていない

```yaml:createIAMUser.yaml
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  MyPassword:
    Type: String
    NoEcho: true

Resources:
  AWSRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - "servicecatalog.amazonaws.com"
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: toExecutionProduct
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - access-analyzer:ValidatePolicy
                  - cloudformation:CreateStack
                  - cloudformation:DeleteStack
                  - cloudformation:DescribeStackEvents
                  - cloudformation:DescribeStacks
                  - cloudformation:GetTemplateSummary
                  - cloudformation:SetStackPolicy
                  - cloudformation:ValidateTemplate
                  - cloudformation:UpdateStack
                  - ec2:*
                  - iam:CreatePolicy
                  - iam:attachRolePolicy
                  - s3:GetObject
                  - servicecatalog:*
                  - sns:*
                Resource: '*'        

  AWSUser:
    Type: AWS::IAM::User
    Properties:
      LoginProfile:
        Password: !Ref MyPassword
        PasswordResetRequired: false
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSServiceCatalogEndUserFullAccess
      Policies:
        - PolicyName: getS3
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: '*'
```
作成できたら、二つ目の制約を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/3ad69335-c9a3-210c-e21f-e8e522f2c128.png)
今度は起動を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/a610d7ef-9057-77fd-69bd-23fab21b06ce.png)
CFnで作成したIAMロールを指定して、作成をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/dd6ceb89-a955-540f-cf1e-9421ce3b6fc4.png)
先ほど作成したテンプレートの制約と合わせて、二つできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/08a25a0a-218d-2763-df97-2602173c1f21.png)



## ステップ 7: ポートフォリオへのアクセス権限のエンドユーザーへの付与
公式とはちょっと説明が異なります。対象のタブを選んで「アクセス権の付与」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/02437700-7dd9-9a8e-da76-96910cf906e7.png)
今回追加するのはユーザーなので、ユーザータブから指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/3d23a4a5-ea94-950b-fce6-11e39e2b5b1c.png)
タブを更新して、追加されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/faad3823-9f31-c192-f619-0f822f8ce3a4.png)

## ステップ 8: エンドユーザーのエクスペリエンスをテストする
### 製品の起動
作成したユーザーでサインインすると、コンソールから以下のように見れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/6e59113d-af05-9759-28a3-a76ea7aa3176.png)
製品を起動、をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/478b4e24-92ca-1c1b-b670-d65c95e9a09a.png)
公式通りに名前を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/2f0c91a7-0a4e-61f2-fd37-4c01182ae175.png)
パラメータは、先ほど作ったキーを指定して、IPは自分のもの(0.0.0.0/0)でもOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/7eead409-a5a9-c3fe-f967-9083d3b676e9.png)
起動を開始しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/059dd95f-4b3a-04f5-4b96-27e3f58ed9b5.png)
うまく起動できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/349e9b21-eebb-a690-8aa2-90c50665e9f1.png)
ユーザにEC2の起動権限を付与していませんが、起動制約に指定したIAMロールが起動してくれたようです。

CloudFormationのスタックで作られています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/f28059e4-b4de-116f-e048-41acd84ec473.png)


### 製品で作られたEC2につなぐ
WindowsのPowerShellから、繋いでみます。コマンドは`ssh -i "[作成したキーファイル].pem" ec2-user@[インスタンスのPublicDNSName]`になります。
EC2のコンソールから見れるのであれば、対象のインスタンスの接続の情報から見れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/179fb9b5-e997-9007-c7ba-c00c94932dc4.png)

今回はWindowsからSSHでつなぎます。最初のほうで作成したキーファイルの権限を制限する必要があります。
Windowsの場合はキーファイルの権限を変更するより、ユーザフォルダで動かした方が楽ですので、以下を参考に、そこにファイルを移動して、そこから起動します。

https://blog.y-yuki.net/entry/2021/04/11/100000


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/d0ba51f0-8ca2-d507-2169-ead870df3aab.png)

シフトキーと右クリックでPowerShellを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1d10263a-54de-e69c-753d-8b5e81a8f698.png)

先ほどのSSHコマンドを実行して、無事繋ぐことができました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/249ec7df-55fe-beb6-2b51-d2bb8ba6f8a3.png)


### 製品の終了(削除)
起動したユーザで、製品を終了させます。
プロビジョニングされた製品、の一覧に、作成したものが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/bf60602c-ec3a-ba55-90f0-5f580425e0f4.png)

選択して[アクション]-[終了]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e912cdf2-46ee-e9fa-2afb-a73f77c5f0c9.png)

”終了”といれて、プロビジョニングされた製品を終了させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c8b6a01f-8407-5175-a7ae-f588113d0281.png)

終了中になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/78af27ee-26e7-aaf2-8927-1bce9b21e483.png)
スタックの方で削除処理が流れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/93dc13c8-6bc4-fab9-ab9a-2bffcb426459.png)

削除が完了すると、ユーザー側からは製品がなくなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/bab7fdbb-e58f-91f9-9edf-9385e1e7f717.png)

スタックも削除完了しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/2abcf016-8120-4831-b0f8-2f37aeb1c145.png)


## 片付け

- 先に製品から削除します。
    - 製品リストから選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/260de6bc-a1c6-194c-f42c-e999bd260196.png)
    - アクションから　製品の削除　を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/b12be5cd-2357-f988-ed52-7edcdc6f4741.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/784e2614-c222-69df-8487-24764fa7bc92.png)

- 次にポートフォリオを削除します。
    - 作ったポートフォリオからアクセス権を削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/742c276f-fc49-0dbe-50da-7e186e62bd87.png)
    - 関連付けされたリソースがなくなった後、ポートフォリオ自身を削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c0120f8f-a8f9-7dcd-a2cd-cdc71396e839.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/86ba2f0c-a2a8-908e-6627-b050cc507fd4.png)

- CFnで作成したユーザーとロールは、対象のスタックを削除します。

# おわりに
今回はService Catalogを触ってみました。
色々な立場の人がAWSを使う場合、それぞれの方にさせたいことをポートフォリオを使って指定する、などに使う機能と感じました。
この記事がどなたかのお役に立てれば幸いです。