CloudFormationを使用してAWS Service Catalog入門

目次

CloudFormationを使用してAWS Service Catalog入門

本ページでは、AWS Service Catalogを取り上げます。

Service Catalog を使用すると、組織は一般的に導入されているITサービスを一元管理でき、組織が一貫したガバナンスを実現し、コンプライアンス要件を満たすのに役立ちます。エンドユーザーは、組織によって設定された制約に従って、必要な承認済みの IT サービスのみをすばやくデプロイできます。

Service Catalog とは

今回はService Catalog入門ということで、以下のページで取り上げられている内容をCloudFormationを使用して構築することを目的とします。

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

構築する環境

Diagram of introduction to AWS Service Catalog using CloudFormation

IAMユーザと、これが所属するIAMグループを作成します。

Service Catalogポートフォリオを作成します。
ポートフォリオ内に、以下のリソースを製品として登録します。

  • EC2インスタンス
  • セキュリティグループ

上記のリソースはCloudFormationテンプレートファイルで定義され、これをポートフォリオに関連づけることで製品を作成します。

以下の2つの制約を設定します。

  • 製品起動時に、テンプレートのパラメータが取り得る値に関する制約
  • 製品起動時に、Service Catalogが引き受けるIAMロールに関する制約

先述のIAMグループを対象として、このポートフォリオにアクセスする権限を与えます。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/124

テンプレートファイルのポイント解説

(参考)IAMユーザ・グループ

Resources:
  Group:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Sub "${Prefix}-Endusers"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSServiceCatalogEndUserFullAccess
        - arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess

  User:
    Type: AWS::IAM::User
    Properties:
      Groups:
        - !Ref Group
      LoginProfile:
        Password: !Ref IAMUserPassword
        PasswordResetRequired: false
      UserName: !Sub "${Prefix}-User"
Code language: YAML (yaml)

Service Catalogへのアクセスを許可するIAMユーザと、そのユーザが所属するIAMグループです。

以下のページに記載されている内容に従って設定します。

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

ポイントはIAMグループにアタッチするIAMポリシーです。
グループに所属するユーザに対して、Service Catalogにアクセスする権限を与えるために、AWS管理ポリシーAWSServiceCatalogEndUserFullAccessをアタッチします。
また製品起動後に、作成したEC2インスタンス等の設定状況を確認するために、同じくAmazonEC2ReadOnlyAccessをアタッチします。

製品用テンプレート

AWSTemplateFormatVersion: 2010-09-09

Description: |
  AWS Service Catalog sample template. Creates an Amazon EC2 instance
  running the Amazon Linux AMI. The AMI is chosen based on the region
  in which the stack is run. This example creates an EC2 security
  group for the instance to give you SSH access. **WARNING** This
  template creates an Amazon EC2 instance. You will be billed for the
  AWS resources used if you create a stack from this template.


Parameters:
  InstanceType:
    Description: EC2 instance type.
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t2.small
      - t2.medium
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge


Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Instance configuration
        Parameters:
          - InstanceType
    ParameterLabels:
      InstanceType:
        default: "Server size:"


Mappings:
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-08842d60
    us-west-2:
      HVM64: ami-8786c6b7
    us-west-1:
      HVM64: ami-cfa8a18a
    eu-west-1:
      HVM64: ami-748e2903
    ap-southeast-1:
      HVM64: ami-d6e1c584
    ap-northeast-1:
      HVM64: ami-35072834
    ap-southeast-2:
      HVM64: ami-fd4724c7
    sa-east-1:
      HVM64: ami-956cc688
    cn-north-1:
      HVM64: ami-ac57c595
    eu-central-1:
      HVM64: ami-b43503a9


Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType
      SecurityGroups:
        - !Ref InstanceSecurityGroup
      ImageId: !FindInMap
        - AWSRegionArch2AMI
        - !Ref AWS::Region
        - HVM64

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0


Outputs:
  PublicDNSName:
    Description: Public DNS name of the new EC2 instance
    Value: !GetAtt EC2Instance.PublicDnsName

  PublicIPAddress:
    Description: Public IP address of the new EC2 instance
    Value: !GetAtt EC2Instance.PublicIp
Code language: YAML (yaml)

以下のページに記載されているCloudFormationテンプレートファイルを、一部変更した上で、YAML化しました。

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

変更点は以下の通りです。

  • キーペアに関する設定を削除。
  • SSHのソースの制限に関する設定を削除。

Service Catalog

ポートフォリオ

ポートフォリオとは、製品の集合で、設定情報も含まれます。

ポートフォリオ
Resources:
  Portfolio:
    Type: AWS::ServiceCatalog::Portfolio
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      Description: Sample portfolio that contains a single product.
      DisplayName: Engineering Tools
      ProviderName: IT (it@example.com)
Code language: YAML (yaml)

以下のページに記載されている内容に従って設定します。

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

製品

製品とは、AWS でのデプロイに利用できるようにする IT サービスのことです。製品は、EC2 インスタンス、ストレージボリューム、データベース、モニタリング設定、ネットワーキングコンポーネント、パッケージ化された AWS Marketplace 製品など、1 つ以上の AWS リソースで構成されます。

製品
Resources:
  CloudFormationProduct:
    Type: AWS::ServiceCatalog::CloudFormationProduct
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      Description: Cloud development environment configured for engineering staff. Runs AWS Linux.
      Name: Linux Desktop
      Owner: IT
      ProvisioningArtifactParameters:
        - Description: Base Version
          DisableTemplateValidation: true
          Info:
            LoadTemplateFromURL: !Sub "https://${TemplateBucketName}.s3.${AWS::Region}.amazonaws.com/${Prefix}/development-environment.yaml"
          Name: v1.0
      ReplaceProvisioningArtifacts: false
      SupportDescription: Contact the IT department for issues deploying or connecting to this product.
      SupportEmail: ITSupport@example.com
      SupportUrl: https://wiki.example.com/IT/support 
Code language: YAML (yaml)

以下のページに記載されている内容に従って設定します。

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

LoadTemplateFromURLプロパティで、先述の製品用CloudFormationテンプレートファイルを指定します。
今回は同ファイルをS3バケットにアップロードし、同ファイルのURLを指定します。

ポートフォリオと製品が定義できましたので、以下のリソースを定義して、これらを関連付けます。

Resources:
  PortfolioProductAssociation:
    Type: AWS::ServiceCatalog::PortfolioProductAssociation
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      PortfolioId: !Ref Portfolio
      ProductId: !Ref CloudFormationProduct
Code language: YAML (yaml)

制約

制約では、製品の起動コンテキストを制御 (起動制約) したり、AWS CloudFormation テンプレートにルールを追加 (テンプレート制約) したりできます。

ステップ 5: テンプレート制約を追加してインスタンスサイズを制限する
Resources:
  LaunchTemplateConstraint:
    Type: AWS::ServiceCatalog::LaunchTemplateConstraint
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      PortfolioId: !Ref Portfolio
      ProductId: !Ref CloudFormationProduct
      Rules: |
        {
          "Rule1": {
            "Assertions": [
              {
                "Assert" : {"Fn::Contains": [["t2.micro", "t2.small"], {"Ref": "InstanceType"}]},
                "AssertDescription": "Instance type should be t2.micro or t2.small"
              }
            ]
          }
Code language: YAML (yaml)

以下のページに記載されている内容に従って設定します。

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

先述のCloudFormationテンプレートファイルにおいて、Parametersセクションで、起動するEC2インスタンスのサイズを選択することができました。
テンプレートに関する制約を定義すると、この取り得る値を制限することができます。

制約の具体的な内容はRulesプロパティで行います。
上記のページに従い、今回は2つのサイズ(t2.micro, t2.small)のみを選択できるようにしています。
なお本プロパティはJSON形式の文字列である必要がありますので、ご注意ください。

IAMロールに関する制約

起動制約は、エンドユーザーが製品を起動するときにがService Catalog が引き受ける IAM ロールを指定します。

ステップ 6: IAM ロールを割り当てる起動制約を追加する
Resources:
  LaunchRoleConstraint:
    DependsOn:
      - Portfolio
      - CloudFormationProduct
      - PortfolioProductAssociation
      - PortfolioPrincipalAssociation
      - LaunchTemplateConstraint
    Type: AWS::ServiceCatalog::LaunchRoleConstraint
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      Description: !Sub "Launch as ${IAMRoleArn}"
      PortfolioId: !Ref Portfolio
      ProductId: !Ref CloudFormationProduct
      RoleArn: !Ref IAMRoleArn
Code language: YAML (yaml)

以下のページに記載されている内容に従って設定します。

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

以下がService Catalogが引き受けるIAMロールです。

Resources:
  LinuxDesktopLaunchRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - servicecatalog.amazonaws.com
      Policies:
        - PolicyName: LinuxDesktopPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudformation:CreateStack
                  - cloudformation:DeleteStack
                  - cloudformation:DescribeStackEvents
                  - cloudformation:DescribeStacks
                  - cloudformation:GetTemplateSummary
                  - cloudformation:SetStackPolicy
                  - cloudformation:ValidateTemplate
                  - cloudformation:UpdateStack
                Resource: "*"
              - Effect: Allow
                Action:
                  - servicecatalog:*
                Resource: "*"
              - Effect: Allow
                Action:
                  - sns:*
                Resource: "*"
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: "*"
                Condition:
                  StringEquals:
                    s3:ExistingObjectTag/servicecatalog:provisioning: true
              - Effect: Allow
                Action:
                  - ec2:*
                Resource: "*"
Code language: YAML (yaml)

ポートフォリオへのアクセス権限

ポートフォリオへのアクセス権をユーザーに付与すると、ユーザーはポートフォリオを閲覧して、それに含まれる製品を起動できます。

許可
Resources:
  PortfolioPrincipalAssociation:
    Type: AWS::ServiceCatalog::PortfolioPrincipalAssociation
    Properties:
      AcceptLanguage: !Ref AcceptLanguage
      PortfolioId: !Ref Portfolio
      PrincipalARN: !Ref IAMGroupArn
      PrincipalType: IAM
Code language: YAML (yaml)

以下のページに記載されている内容に従って設定します。

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

先述のIAMグループに対して、ポートフォリオへのアクセス権限を与えます。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

なお今回のCloudFormationスタックを作成する際のコマンドのパラメータは以下となります。

$ aws cloudformation create-stack \
--stack-name fa-124 \
--template-url [s3-bucket-url]/fa-124.yaml \
--capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
Code language: Bash (bash)

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • IAMユーザ:fa-124-User
  • IAMグループ:fa-124-Endusers
  • ポートフォリオ:Engineering Tools
  • 製品:Linux Desktop
  • Service Catalog用IAMロール:fa-124-IAMStack-1URUPL1I86Y-LinuxDesktopLaunchRole-A2RWHWI8I1HD

AWSマネージメントコンソールから各種リソースを確認します。

IAMユーザを確認します。

Detail of IAM 1.

確かにユーザが作成されています。
このユーザがfa-124-Endusersに所属していることもわかります。

IAMグループを確認します。

Detail of IAM 2.

こちらも正常に作成されていることがわかります。
2つのIAMポリシーがアタッチされていることもわかります。

ポートフォリオを確認します。

Detail of Service Catalog 1.

ポートフォリオ内に1つの製品が作成されていることがわかります。

この製品の中身を確認します。

Detail of Service Catalog 2.

Versionsタブを見ると、v1.0が作成されていることがわかります。

Detail of Service Catalog 3.

バージョンの詳細を見ると、製品用のCloudFormationテンプレートが確認できます。
このように製品用CloudFormationテンプレートはバージョンに紐づくものであることがわかります。

制約を確認します。

Detail of Service Catalog 4.

2つの制約が設定されていることがわかります。
テンプレートと、製品起動時に引き受けるIAMロールに関するものです。

Detail of Service Catalog 5.
Detail of Service Catalog 6.

どちらも正常に作成されていることがわかります。

ポートフォリオへのアクセス権限を確認します。

Detail of Service Catalog 7.

IAMグループfa-124-Endusersに所属しているユーザにアクセス権があることがわかります。

動作確認

準備が整いましたので、IAMユーザ(fa-124-User)でAWSマネージメントコンソールにサインインします。

Detail of Service Catalog 8.

ログイン後、Service Catalogのページにアクセスすると、今回作成した製品が確認できます。
確かに本ユーザへのアクセス権限が付与されていることがわかります。

製品を起動します。
「Launch product」をクリックします。

Detail of Service Catalog 9.

プロビジョニングされた製品名として、「fa-124」を指定します。

先ほど確認した通り、製品のバージョンは「v1.0」が用意されていますので、これを指定します。

Parametersで製品用CloudFormationテンプレートのパラメータを指定します。
画像の通り、本来は7つのインスタンスサイズが選択可能なのですが、2つの値が選択可能です。
これはテンプレート制約によるものです。
今回はt2.microを指定します。

Detail of Service Catalog 10.

確かに製品が起動しています。

Resourcesを見ると、EC2インスタンスとセキュリティグループが作成されていることがわかります。

CloudFormationを確認します。

Detail of CloudFormation 1.
Detail of CloudFormation 2.

Service Catalogの製品の起動によって、新しいCloudFormationスタックが作成されていることがわかります。

最後に作成された2リソースを確認します。

Detail of EC2 1.
Detail of EC2 2.

確かにEC2インスタンスとセキュリティグループが作成されています。
このようにService Catalogを使用することによって、指定したユーザに対して、特定の条件を敷いた上で、リソース群を作成することを許可することができます。

まとめ

CloudFormationを使用して、Service Catalog入門しました。

目次