Como faço para corrigir o erro “Não é possível validar as seguintes configurações de destino” no AWS CloudFormation?

6 minuto de leitura
0

Eu assino um tópico do Amazon Simple Notification Service (Amazon SNS) ou uma função do AWS Lambda nas notificações de eventos do Amazon Simple Storage Service (Amazon S3). Se você receber o seguinte erro: “Não é possível validar as seguintes configurações de destino.” Quando tento definir uma dependência na política de tópicos do SNS a partir do bucket do S3 em meu modelo, recebo um erro circular de validação de dependência.

Breve descrição

Devido à forma como o AWS CloudFormation lida com a ordenação de dependências, as notificações de eventos do Amazon S3 são definidas como um atributo do bucket do S3. Essas notificações são estabelecidas quando o recurso de bucket do S3 é criado.

Para evitar um erro, você deve criar recursos na seguinte ordem:

  1. Crie o tópico do SNS, porque o bucket do S3 faz referência ao tópico do SNS.
  2. Crie o bucket do S3, porque a política de tópicos do SNS faz referência ao bucket do S3 e ao tópico do SNS.

Antes de inscrever um tópico do SNS nas notificações de eventos do S3, você deve especificar uma política de tópico (AWS::SNS::TopicPolicy) com as permissões apropriadas. Essa política de tópico deve existir antes de você criar a assinatura.

Experimente uma das estratégias a seguir para evitar o erro “Não é possível validar as seguintes configurações de destino”:

  • Especificar um valor para BucketName em seu modelo do AWS CloudFormation
  • Criar uma pilha e, em seguida, executar uma atualização da pilha

Resolução

Especificar um valor para BucketName em seu modelo do AWS CloudFormation

Use um nome estático para seu bucket do S3 especificando um valor para a propriedade BucketName no recurso S3Bucket do seu modelo do AWS CloudFormation. Isso elimina a necessidade de incluir {"Ref”:“paramBucketName"} na política de tópicos do SNS. Isso remove a dependência intrínseca entre a política de tópicos do SNS e o Amazon S3.

O exemplo de modelo do AWS CloudFormation a seguir especifica um valor codificado (-Bucket-Name-) para a propriedade BucketName. Em seu modelo, substitua todas as instâncias de -Bucket-Name- pelo nome do seu bucket.

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        "-Bucket-Name-"
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DependsOn": [
        "SNSTopicPolicy"
      ],
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "BucketName": "-Bucket-Name-",
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

**Observação:**o recurso S3Bucket tem um valor DependsOn explícito definido como SNStopicPolicy. Esse atributo especifica que o modelo cria o recurso SNStopicPolicy antes do recurso S3Bucket.

Para usar o mesmo modelo do AWS CloudFormation para buckets S3 com nomes diferentes, defina um parâmetro para o nome do bucket. O parâmetro permite que você use o mesmo modelo para diferentes nomes de bucket passando o nome do bucket como parâmetro durante a criação da pilha.

Para usar o modelo de exemplo a seguir, você deve passar o nome do bucket como parâmetro paramBucketName durante a criação da pilha.

{
  "Parameters": {
    "paramBucketName": {
      "Type": "String",
      "Description": "Bucket Name"
    }
  },
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "paramBucketName"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DependsOn": [
        "SNSTopicPolicy"
      ],
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "BucketName": {
          "Ref": "paramBucketName"
        },
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

Criar uma pilha e, em seguida, executar uma atualização da pilha

Divida a criação da pilha em dois estágios. Primeiro, crie a pilha, mas não especifique a propriedade NotificationConfiguration no recurso S3Bucket. Em seguida, execute uma atualização da pilha para adicionar a notificação de evento do S3. Isso evita definir a notificação de evento do S3 antes que a política de tópicos do SNS seja criada.

1.    Crie todos os recursos, incluindo a política de tópicos do SNS. Por exemplo:

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "S3Bucket"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccessControl": "BucketOwnerFullControl"
      }
    }
  }
}

2.    Atualize a pilha para adicionar a notificação de evento do S3. Por exemplo:

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "S3Bucket"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

Observação: você pode usar o AWS CloudFormation Template Flip para converter seus modelos do AWS CloudFormation entre os formatos JSON e YAML.


Informações relacionadas

Como evito o erro “Não é possível validar as seguintes configurações de destino” com as notificações de eventos do Lambda no AWS CloudFormation?

Atualizações da pilha do AWS CloudFormation

Configuração de notificações do Amazon SNS

AWS OFICIAL
AWS OFICIALAtualizada há 2 anos