Step FunctionsでParameter Storeの値を入れ替える

# はじめに
AWS Systems Managerのパラメーターストアに接続先を格納しておいて、障害発生時に別の接続先に書き換える、という構成があるようです。

今回は、パラメーターストアを2つ作成し、一方を稼働系、もう一方を待機系の情報を格納しておいて、Step Functionsで入れ替えるような構成を作ってみました。

# 概要

- 以下の二つのパラメーターストアを作ります
    - PrimaryParameter
        - 今回は最初に`tokyo-endpoint`という値を入れておきます
    - SecondaryParameter
        - 今回は最初に`osaka-endpoint`という値を入れておきます
- 上記2つの値を入れ替える仕組みを、Step Functionsで作ります


# ソース
概要の仕組みを作成するCloudFormationテンプレートは以下になります。

```yaml
AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  PrimaryParameterValue:
    Type: String
    Default: tokyo-endpoint
  SecondaryParameterValue:
    Type: String
    Default: osaka-endpoint

Resources:
  PrimaryParameterStore:
    Type: AWS::SSM::Parameter
    Properties:
      Name: PrimaryParameter
      Type: String
      Value: !Ref PrimaryParameterValue
  SecondaryParameterStore:
    Type: AWS::SSM::Parameter
    Properties:
      Name: SecondaryParameter
      Type: String
      Value: !Ref SecondaryParameterValue

  roleForStateMachine:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: write-parameter
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ssm:GetParameters
                  - ssm:PutParameter
                Resource: 
                  - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${PrimaryParameterStore}
                  - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${SecondaryParameterStore}

  switchStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      RoleArn: !GetAtt roleForStateMachine.Arn
      Definition:
        StartAt: GetParameters
        States:
          GetParameters:
            Type: Task
            Parameters:
              Names:
                - !Ref PrimaryParameterStore
                - !Ref SecondaryParameterStore
            Resource: 'arn:aws:states:::aws-sdk:ssm:getParameters'
            ResultPath: $.getParameters
            ResultSelector:
              primary.$: 'States.ArrayGetItem($.Parameters,0)'
              secondary.$: 'States.ArrayGetItem($.Parameters,1)'
            Next: Parallel
          Parallel:
            Type: Parallel
            Branches:
              -
                StartAt: putPrimaryParameter
                States:
                  putPrimaryParameter:
                    Type: Task
                    Parameters:
                      Name.$: $.primary.Name
                      Value.$: $.secondary.Value
                      Overwrite: 'true'
                    Resource: 'arn:aws:states:::aws-sdk:ssm:putParameter'
                    InputPath: $.getParameters
                    End: true
              -
                StartAt: putSecondaryParameter
                States:
                  putSecondaryParameter:
                    Type: Task
                    End: true
                    Parameters:
                      Name.$: $.secondary.Name
                      Value.$: $.primary.Value
                      Overwrite: 'true'
                    Resource: 'arn:aws:states:::aws-sdk:ssm:putParameter'
                    InputPath: $.getParameters
            End: true
```
作成されるState Machineは以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e21b5c50-fe29-610a-d7fe-3ff7cadf26db.png)

1. GetParameters:2つのパラメーターストアの値を取得
1. Parallelで、以下の2つを実行します
    1. 取得済みのPrimaryParameterの値を、SecondaryParameterにセット
    1. 取得済みのSecondaryParameterの値を、PrimaryParameterにセット


# 実行

## 実行前
実行前の状態を確認しておきます。

| パラメーター名 | 値 |
| ---- | ---- |
| PrimaryParameter | tokyo-endpoint |
| SecondaryParameter | osaka-endpoint |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/7493f653-0dcc-4e83-c39e-2868cc73fdbf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/33ea23df-d6e5-4662-faa4-df1076c77e2c.png)

## State Machineを実行
State Machineを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/0e61df56-c3c3-ffa0-4c13-2c6ddeb7a6b9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c26dccab-669d-0b7c-a9bc-35de6d39079a.png)


## 実行後
実行後は、値が入れ替わっていることを確認します。

| パラメーター名 | 値 |
| ---- | ---- |
| PrimaryParameter | osaka-endpoint |
| SecondaryParameter | tokyo-endpoint |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/4f36bd45-22a8-170c-612f-f0d2f1fdbf18.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/23a81f1e-be00-f210-b21a-5a1657d2e111.png)

# おわりに

稼働系、待機系の情報を入れ替える仕組みを、Step Functionsで作ってみました。
データベースのテーブルで稼働系-待機系を扱う際にシノニムを使って作っていますが、それをパラメーターストアでやってみようと思って作ってみました。

この記事がどなたかのお役に立てれば幸いです。