この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
コンサル部のとばち(@toda_kk)です。
2021年8月に発表された新サービスであるAmazon MemoryDB for Redisについて、CloudFormationを使ってリソース管理できるようになりました。
Amazon MemoryDB for Redisは、高速なインメモリデータベースでありつつデータの永続化をサポートしているRedis互換のマネージドサービスです。詳細は下記ページをご参照ください。
なお、2021年10月からは東京リージョンでも利用可能になっています。
Amazon MemoryDB for RedisのCloudFormationリソースタイプ
公式ドキュメントが公開されたので、早速眺めてみます。
2021年11月2日現在、サポートされているCloudFormationのリソースタイプは下記の通りです。
- AWS::MemoryDB::ACL
- AWS::MemoryDB::Cluster
- AWS::MemoryDB::ParameterGroup
- AWS::MemoryDB::SubnetGroup
- AWS::MemoryDB::User
Cluster、ParameterGroup、SubnetGroup
MemoryDB for Redisは、ElastiCache for Redisと同様にVPC内に配置されるリソースであり、サブネットグループによって配置するAvailability Zoneやサブネットを指定し、パラメーターグループによってRedisエンジンのパラメーターを設定します。
また、クラスターモードのみがサポートされており、シャード数(NumShards
)やレプリカ数(NumReplicasPerShard
)を指定する必要があります。レプリカ数を1以上で設定する場合は、指定するサブネットグループに複数のAZが含まれている必要があります。
ACL
MemoryDB for Redisではセキュリティグループをサポートしていますが、それとは別にアクセスコントロールリスト(ACL)という形でユーザー毎のアクセス制御を設定できます。
このACLは、Redisバージョン6にて標準でサポートされている機能です。Redis ACL
コマンドを通じて、ユーザーやユーザーグループを作成し、実行可能なコマンドやデータのアクセス制御を設定することができます。
ただし、MemoryDB for RedisにおいてはACL
コマンドの機能は一部制限されており、ユーザーの作成や権限の変更といった書き込みベースの処理がサポートされていません。そのため、ユーザー作成といった操作を実行したいときは、MemoryDB for Redisの機能としてマネジメントコンソールやCLIやCloudFormationから行う必要があります。
redis-cliでRedisに接続した後、ACL HELP
を実行することでサポートされているコマンドを確認できます。まずは、Redisバージョン6のコンテナイメージを引っ張ってきてローカル環境などで起動した上で、素のRedisでサポートされているコマンドを確認してみます。
Dockerで起動したRedisでACL HELPした場合
$ sudo docker pull redis:6
$ sudo docker run -d -p 6379:6379 redis:6
$ redis-cli -h localhost
localhost:6379> ACL HELP
1) ACL <subcommand> [<arg> [value] [opt] ...]. Subcommands are:
2) CAT [<category>]
3) List all commands that belong to <category>, or all command categories
4) when no category is specified.
5) DELUSER <username> [<username> ...]
6) Delete a list of users.
7) GETUSER <username>
8) Get the user's details.
9) GENPASS [<bits>]
10) Generate a secure 256-bit user password. The optional `bits` argument can
11) be used to specify a different size.
12) LIST
13) Show users details in config file format.
14) LOAD
15) Reload users from the ACL file.
16) LOG [<count> | RESET]
17) Show the ACL log entries.
18) SAVE
19) Save the current config to the ACL file.
20) SETUSER <username> <attribute> [<attribute> ...]
21) Create or modify a user with the specified attributes.
22) USERS
23) List all the registered usernames.
24) WHOAMI
25) Return the current connection username.
26) HELP
27) Prints this help.
次に、MemoryDB for Redisに接続して確認してみます。ちなみに、クラスターの設定でTLS接続を有効にしている場合は--tls
オプションが必要になります。また、クラスターモードで接続したい場合は-c
オプションを付与します。
MemoryDB for Redisに接続してACL HELPした場合
$ redis-cli -h xxxxxx.cluster-name.xxxxxx.memorydb.ap-northeast-1.amazonaws.com --tls -c
xxxxxx.cluster-name.xxxxxx.memorydb.ap-northeast-1.amazonaws.com:6379> ACL HELP
1) ACL <subcommand> [<arg> [value] [opt] ...]. Subcommands are:
2) LIST -- Show user details in config file format.
3) USERS -- List all the registered usernames.
4) GETUSER <username> -- Get the user details.
5) CAT -- List available categories.
6) CAT <category> -- List commands inside category.
7) GENPASS [<bits>] -- Generate a secure user password.
8) WHOAMI -- Return the current connection username.
9) LOG [<count> | RESET] -- Show the ACL log entries.
10) HELP
11) Prints this help.
素のRedisと比べて、MemoryDB for Redisではサポートされているコマンドが少ないことがわかります。
これはElastiCache for Redisでも同様です。Redis標準ではAUTH
コマンドによるユーザー認証がサポートされていますが、より柔軟な権限制御の方法としてRBAC(Role-Based Access Control)という形でRedis ACL
をサポートしています。
- Authenticating users with the Redis AUTH command - Amazon ElastiCache for Redis
- Authenticating users with Role-Based Access Control (RBAC) - Amazon ElastiCache for Redis
Redisでは当初からAUTH
コマンドによる認証がサポートされていたのですが、バージョン6からAUTH
の拡張と共にACL
が追加され、より柔軟な権限制御を実現できるようになったという背景があります。ElastiCache for RedisではRedisエンジンのバージョン6をサポートするにあたり、RBACという形でRedis ACL
を提供するようになりました。
これを受けて、MemoryDB for RedisではCloudFormationのリソースタイプにもあるようにACL
とUser
をAWSリソースとして管理できるようにサポートしているようです。デフォルトではopen-access
という名前のACLが作成されており、default
ユーザーが登録されています。
User
上述のACLで管理するユーザーを作成するリソースタイプです。形式は下記のようになっています。
AWS::MemoryDB::User
Type: AWS::MemoryDB::User
Properties:
AccessString:
String
AuthenticationMode: Json
Tags:
- Tag
UserName: String
AccessString
は、ユーザーに許可する操作権限を指定するパラメーターです。on ~* &* +@all
といった形式で記述します。詳細は前掲の MemoryDB for Redisのドキュメント もしくは Redisの公式ドキュメント をご参照ください。
AuthenticationMode
はJSON形式で指定します。MemoryDBにおけるアクションCreateUser
のAPIリファレンスによると、Type
とPasswords
を指定する必要がありそうです。
ここで、上述のdefault
ユーザーの設定値をAWS CLIから確認してみます。すると、Authentication.Type
がno-password
となっていることがわかります。
これはつまり、パスワードなしでRedisに接続できるユーザーということになります。ElastiCache for Redisの場合でも、AUTH認証やRBACのことを特に意識していない状態で利用していれば、このdefault
ユーザーを使ってアクセスしていることになります。
$ aws memorydb describe-users
{
"Users": [
{
"Name": "default",
"Status": "active",
"AccessString": "on ~* &* +@all",
"ACLNames": [
"open-access"
],
"MinimumEngineVersion": "6.0",
"Authentication": {
"Type": "no-password"
},
"ARN": "arn:aws:memorydb:ap-northeast-1:123456789012:user/default"
}
]
}
しかし、データタイプAuthenticationMode
のリファレンスを参照すると、次のような記載があります。
Indicates whether the user requires a password to authenticate. All newly-created users require a password.
つまり、新たにユーザーを作成する場合はパスワードが必要になり、no-password
は実態としてはdefault
ユーザーでしか利用できないようです。
CloudFormationからリソース作成してみる
必要なリソースタイプがわかったので、CloudFormationを使って一通りのリソースを作成してみます。以下は、簡単なサンプルとしてご利用いただければと思います。
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
SampleCluster:
Type: AWS::MemoryDB::Cluster
Properties:
ClusterName: sample-cluster
ACLName: !Ref SampleACL
NodeType: db.r6g.large
NumReplicasPerShard: 1
NumShards: 1
ParameterGroupName: !Ref SampleParameterGroup
SecurityGroupIds:
- sg-xxxxxxxxxxxxxxxxx
- sg-yyyyyyyyyyyyyyyyy
SubnetGroupName: !Ref SampleSubnetGroup
TLSEnabled: true
SampleSubnetGroup:
Type: AWS::MemoryDB::SubnetGroup
Properties:
SubnetGroupName: sample-subnet-group
SubnetIds:
- subnet-xxxxxxxxxxxxxxxxx
- subnet-yyyyyyyyyyyyyyyyy
- subnet-zzzzzzzzzzzzzzzzz
SampleParameterGroup:
Type: AWS::MemoryDB::ParameterGroup
Properties:
ParameterGroupName: sample-parameter-group
Family: memorydb_redis6
SampleACL:
Type: AWS::MemoryDB::ACL
Properties:
ACLName: sample-acl
UserNames:
- !Ref SampleUser
SampleUser:
Type: AWS::MemoryDB::User
Properties:
UserName: sample-user
AccessString:
on ~* &* +@all
AuthenticationMode: {
Type: password,
Passwords: [xxxxxxxxxxXXXXX!]
}
意図した通りにリソースが作成されていました。
以上、コンサル部のとばち(@toda_kk)でした。