特定のAWSサービスからのみSQSへのアクセスを許可するアクセスポリシーの設定

# はじめに
特定のサービスのみSQSへのアクセスを許可するポリシー設定についてまとめます。
![スクリーンショット 2022-10-30 22.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/c9e917ce-89e6-d73a-2938-a29c2569d67e.png)

# SQSのアクセスポリシー
今回は、EC2とSNSのみを許可した場合になります。
`Principal`内の`Service`と`Condition`内の`aws:SourceArn`にSQSがアクセスを許可するサービスを記載します。

```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "sns.amazonaws.com",
          "ec2.amazonaws.com"
        ]
      },
      "Action": [
        "sqs:SendMessage",
        "sqs:ReceiveMessage"
      ],
      "Resource": "arn:aws:sqs:ap-northeast-1:111111111111:test-sqs",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": [
            "arn:aws:sns:ap-northeast-1:111111111111:test-sns",
            "arn:aws:ec2:ap-northeast-1:111111111111:instance"
          ]
        }
      }
    }
  ]
}
```
SQSを作成後、下記のタブから設定変更できます。
![スクリーンショット 2022-10-30 22.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0286b588-7845-047c-f171-89cc7215d209.png)


# SQSとSNSをCloudFormationで作成する
CloudFormationで作成する場合、記載量が少ないyml形式での作成を推奨します。
ただし、ポリシーに関しては、コンソール上ではjsonで表示されているため、ymlファイルにjson形式で記載しています。

SQSは、同じアカウント内のEC2と、CloudFormationで作成されるSNSからのみアクセスできるポリシー設定になっております。

SNSは、同じアカウント内のリソースであればアクセスできるポリシーに設定しています。
```yml
AWSTemplateFormatVersion: '2010-09-09'
Description: sqs-sns

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: SQS Configuration
        Parameters:
          - SQSName
      - Label:
          default: SNS Configuration
        Parameters:
          - SNSName

Parameters:
  SQSName:
    Type: String
    Default: test-sqs
  SNSName:
    Type: String
    Default: test-sns

Resources:
  SNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: !Ref SNSName
      TopicName: !Ref SNSName

  SNSTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument: !Sub |
        {
          "Version": "2008-10-17",
          "Statement": [
            {
              "Sid": "__default_statement_ID",
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": [
                "SNS:GetTopicAttributes",
                "SNS:SetTopicAttributes",
                "SNS:AddPermission",
                "SNS:RemovePermission",
                "SNS:DeleteTopic",
                "SNS:Subscribe",
                "SNS:ListSubscriptionsByTopic",
                "SNS:Publish"
              ],
              "Resource": "${SNSTopic}",
              "Condition": {
                "StringEquals": {
                  "AWS:SourceOwner": "${AWS::AccountId}"
                }
              }
            }
          ]
        }
      Topics:
        - !Ref SNSTopic

  SNSSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref SNSTopic
      Endpoint: !GetAtt SQSQueue.Arn
      Protocol: sqs
      RawMessageDelivery: true
      Region: !Ref AWS::Region

  SQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      DelaySeconds: 0
      MaximumMessageSize: 262144
      MessageRetentionPeriod: 345600
      ReceiveMessageWaitTimeSeconds: 20
      VisibilityTimeout: 30
      QueueName: !Ref SQSName

  SQSQueuePolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument: !Sub |
        {
          "Version": "2008-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "ec2.amazonaws.com",
                  "sns.amazonaws.com"
                  ]
              },
              "Action": [
                  "sqs:SendMessage",
                  "sqs:ReceiveMessage"
              ],
              "Resource": "${SQSQueue.Arn}",
              "Condition": {
                "ArnEquals": {
                  "aws:SourceArn": [
                    "${SNSTopic}",
                    "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance"
                  ]
                }
              }
            }
          ]
        }
      Queues:
        - !Ref SQSQueue
```

ちなみに、`SNSSubscription`の`RawMessageDelivery`は、`true`にしています。
これは、rawメッセージ配信を有効にすることで、SQSには、メッセージのみを受け取ることができます。

 
raw メッセージの配信を無効にした場合、SQS側で受け取る情報。
```json
{
  "Type": "Notification",
  "MessageId": "dc1e94d9-56c5-5e96-808d-cc7f68faa162",
  "TopicArn": "arn:aws:sns:us-east-2:111122223333:ExampleTopic1",
  "Subject": "TestSubject",
  "Message": "This is a test message.",
  "Timestamp": "2021-02-16T21:41:19.978Z",
  "SignatureVersion": "1",
  "Signature": "FMG5tlZhJNHLHUXvZgtZzlk24FzVa7oX0T4P03neeXw8ZEXZx6z35==",
  "SigningCertURL": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem",
  "UnsubscribeURL": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:111122223333:ExampleTopic1:e1039402-24e7-40a3-a0d4-797da162b297"
}
```

raw メッセージの配信を有効にした場合、SQS側で受け取る情報。
```
{
  "Message": "This is a test message."
}
````

https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-large-payload-raw-message-delivery.html


# 参考

https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-sqs-policies.html