CloudFormation でリソースを管理していこう!

最近ちょいちょい東京に出没しております、那須です。

先日、CloudFormation の既存リソースのインポート機能が追加されましたね!

aws.amazon.com

普段の運用では AWS コンソールや CLI からリソースを作成したり更新したりすることが多々あると思います。

でも手作業でそれらを管理するのはちょっと大変ですよね。

Excel 等で内容を記載したり更新が入ったら都度管理資料も更新したり。

そして我々人間にはどうしても完璧に忘れずにそれらを管理することが難しく思えます。

そのような問題を解決できる(はずだった?)のが Infrastructure as Code だったりするんですが、最初はそれでよくてもそのうち JSON や YAML 更新するのが面倒になってコンソールから手作業でやっちゃったりするんですよね。

で、気がつけば従来の運用スタイルに戻っていた、なんて方もいらっしゃるんじゃないでしょうか?

しかし、CloudFormation の既存リソースのインポート機能があればまた JSON や YAML での管理に戻れるかもしれませんよ?

この記事はこんな方におすすめ

・最初は CloudFormation で AWS リソースを管理していたけど途中で手作業になっちゃって困ってる方

・これを機に Infrastructure as Code ってのをやってみたい方

・とりあえず最新機能を試してみたい方

注意事項

なんでもかんでもインポートできるわけではないようです。

↓ここにあるリソースタイプだけがインポート対象になるみたいです。

docs.aws.amazon.com

あと、インポートするリソースには下記の DeletionPolicy を CloudFormation テンプレートに記載しておきましょう。

DeletionPolicy: Retain

ではやってみましょう

まずはインポートしたいリソースを決める

少し前にこんなものを作りました。

nasrinjp1.hatenablog.com

API Gateway の勉強をしながらだったので AWS コンソールから手作業で作成しちゃったんですよね。

なのでひとまずこの API Gateway をインポートすることにします。

また、他の仕組みとは独立しているので新規テンプレートとしてインポートしましょう。

CloudFormation テンプレート作成

既存リソースがそのまま作成されるように CloudFormation テンプレートを作成します。

本当に同じ構成で作成されるかどうか、名前などを変えてテスト環境等で実際に確認すると後でエラーで悩むことがなくなりますよ。

今回は↓このようなテンプレートを作成しました。

AWSTemplateFormatVersion: 2010-09-09
Resources:
  RDPAPI:
    Type: AWS::ApiGateway::RestApi
    DeletionPolicy: Retain
    Properties:
      Name: RDPControl
  RDPopenResource:
    Type: AWS::ApiGateway::Resource
    DeletionPolicy: Retain
    Properties:
      RestApiId:
        Ref: RDPAPI
      ParentId:
        Fn::GetAtt:
          - RDPAPI
          - RootResourceId
      PathPart: open
  GetOpenMethod:
    Type: AWS::ApiGateway::Method
    DeletionPolicy: Retain
    Properties:
      Integration:
        Type: AWS
        IntegrationHttpMethod: GET
        Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:create_maintenance_iam_user/invocations"
        IntegrationResponses:
          - StatusCode: 200
      ApiKeyRequired: true
      RestApiId:
        Ref: RDPAPI
      ResourceId:
        Ref: RDPopenResource
      HttpMethod: GET
      AuthorizationType: NONE
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: Empty
  RDPcloseResource:
    Type: AWS::ApiGateway::Resource
    DeletionPolicy: Retain
    Properties:
      RestApiId:
        Ref: RDPAPI
      ParentId:
        Fn::GetAtt:
          - RDPAPI
          - RootResourceId
      PathPart: close
  GetCloseMethod:
    Type: AWS::ApiGateway::Method
    DeletionPolicy: Retain
    Properties:
      Integration:
        Type: AWS
        IntegrationHttpMethod: GET
        Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:delete_maintenance_iam_user/invocations"
        IntegrationResponses:
          - StatusCode: 200
      RestApiId:
        Ref: RDPAPI
      ResourceId:
        Ref: RDPcloseResource
      HttpMethod: GET
      AuthorizationType: NONE
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: Empty

いざインポート!

では実際にやってみましょう!

CloudFormation コンソールからスタックの作成を開き、既存のリソースを使用(リソースをインポート)をクリックします。

確認して次に進みます。

先ほど準備した CloudFormation テンプレートファイルを選択しましょう。

確認して次に進みます。 

先ほど準備した CloudFormation テンプレートファイルを選択しましょう。 

インポートするリソース情報の確認があります。

今回だと、API Gateway の API-ID, リソース ID, メソッドを入力します。 

API の ID やリソース ID は、API Gateway のコンソールでこの四角で囲んだ部分の文字列を入力しましょう。

名前そのものを入力して次に進んでも、最後の確認の画面で「そんなリソースないで!」ってエラーがでます。 

スタックの名前を決めて入力します。 

確認の画面の一番下にこのようにアクション Import で想定しているリソースが表示されていれば OK です。

リソースをインポートを押しましょう。

1分もかからずにインポートできました。

IMPORT_COMPLETEというステータスになっていますね。 

CloudFormation から更新してみよう!

一応、CloudFormation テンプレートを変更して実際に AWS リソースが変更されるかどうかみておきましょう。

今回は簡単に API の名前を「RDPControl」から「RDPControl1」というように末尾に1を追加してみます。

そしてスタックの更新します。

最後の確認画面でアクション Modify と出ていますね。

問題なければスタックを更新しましょう。

UPDATE_COMPLETE になりました。 

API Gateway のコンソールで対象の API を見ると想定通りに名前が変わっていました!

これで CloudFormation で管理できるようになりましたね! 

最後に

CloudFormation の既存リソースのインポート機能は本当に便利ですね。
また CloudFormation のイベントタブを見ると作業履歴が全部残っているので、自分やチームの作業ログとしても使えそうです。
また気を取り直して CloudFormation でリソースを管理していこうと思いました。