diff --git a/docs/resources/aws_sqs_queue.md.erb b/docs/resources/aws_sqs_queue.md.erb
new file mode 100644
index 000000000..a27fc4f23
--- /dev/null
+++ b/docs/resources/aws_sqs_queue.md.erb
@@ -0,0 +1,126 @@
+---
+title: About the aws_sqs_queue Resource
+---
+
+# aws\_sqs\_queue
+
+Use the `aws_sqs_queue` InSpec audit resource to test properties of a single AWS Simple Queue Service queue.
+
+
+
+## Availability
+
+### Installation
+
+This resource is distributed along with InSpec itself. You can use it automatically.
+
+### Version
+
+This resource first became available in v3.1.4 of InSpec.
+
+## Syntax
+
+ # Ensure that a queue exists and has a visibility timeout of 300 seconds
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ it { should exist }
+ its('visibility_timeout') { should be 300 }
+ end
+
+ # You may also use hash syntax to pass the URL
+ describe aws_sqs_queue(url: 'https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ it { should exist }
+ end
+
+## Resource Parameters
+
+### URL
+
+This resource expects a single parameter, the SQS queue URL that uniquely identifies the SQS queue.
+
+See also the [AWS documentation on SQS Queue identifiers](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-general-identifiers.html).
+
+
+
+## Properties
+
+### visibility\_timeout
+
+An integer indicating the visibility timeout of the message in seconds
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('visibility_timeout') { should be 300}
+ end
+
+### maximum\_message\_size
+
+An integer indicating the maximum message size in bytes
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('maximum_message_size') { should be 262144 } # 256 KB
+ end
+
+### delay\_seconds
+
+An integer indicating the delay in seconds for the queue
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('delay_seconds') { should be 0 }
+ end
+
+### message\_retention\_period
+
+An integer indicating the maximum retention period for a message in seconds
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('message_retention_period') { should be 345600 } # 4 days
+ end
+
+### receive\_message\_wait\_timeout\_seconds
+
+An integer indicating the number of seconds an attempt to recieve a message will wait before returning
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('receive_message_wait_timeout_seconds') { should be 2 }
+ end
+
+### is\_fifo\_queue
+
+A boolean value indicate if this queue is a FIFO queue
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ its('is_fifo_queue') { should be false }
+ end
+
+### content\_based\_deduplication
+
+A boolean value indicate if content based dedcuplication is enabled or not
+
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue.fifo') do
+ its('is_fifo_queue') { should be true }
+ its('content_based_deduplication') { should be true }
+ end
+
+
+
+## Matchers
+
+This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).
+
+### exist
+
+Indicates that the URL provided was found. Use `should_not` to test for SQS topics that should not exist.
+
+ # Expect good news
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueue') do
+ it { should exist }
+ end
+
+ # No bad news allowed
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/1212121/MyQueueWhichDoesntExist') do
+ it { should_not exist }
+ end
+
+## AWS Permissions
+
+Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `sqs:GetQueueAttributes` action with Effect set to Allow.
+You can find detailed documentation at [Actions, Resources, and Condition Keys for Amazon SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-using-identity-based-policies.html).
\ No newline at end of file
diff --git a/lib/resource_support/aws.rb b/lib/resource_support/aws.rb
index d057fa161..75eff42c6 100644
--- a/lib/resource_support/aws.rb
+++ b/lib/resource_support/aws.rb
@@ -51,6 +51,7 @@ require 'resources/aws/aws_security_groups'
require 'resources/aws/aws_sns_subscription'
require 'resources/aws/aws_sns_topic'
require 'resources/aws/aws_sns_topics'
+require 'resources/aws/aws_sqs_queue'
require 'resources/aws/aws_subnet'
require 'resources/aws/aws_subnets'
require 'resources/aws/aws_vpc'
diff --git a/lib/resources/aws/aws_sqs_queue.rb b/lib/resources/aws/aws_sqs_queue.rb
new file mode 100644
index 000000000..2a838bf37
--- /dev/null
+++ b/lib/resources/aws/aws_sqs_queue.rb
@@ -0,0 +1,62 @@
+require 'uri'
+
+class AwsSqsQueue < Inspec.resource(1)
+ name 'aws_sqs_queue'
+ desc 'Verifies settings for an SQS Queue'
+ example "
+ describe aws_sqs_queue('https://sqs.ap-southeast-2.amazonaws.com/519527725796/QueueName') do
+ it { should exist }
+ its('visiblity_timeout') { should be 300}
+ end
+ "
+ supports platform: 'aws'
+
+ include AwsSingularResourceMixin
+ attr_reader :arn, :is_fifo_queue, :visibility_timeout, :maximum_message_size, :message_retention_period, :delay_seconds, :receive_message_wait_timeout_seconds, :content_based_deduplication
+
+ private
+
+ def validate_params(raw_params)
+ validated_params = check_resource_param_names(
+ raw_params: raw_params,
+ allowed_params: [:url],
+ allowed_scalar_name: :url,
+ allowed_scalar_type: String,
+ )
+ # Validate the URL
+ unless validated_params[:url] =~ /\A#{URI::DEFAULT_PARSER.make_regexp(%w{https})}\z/
+ raise ArgumentError, 'Malformed URL for SQS. Expected an ARN of the form ' \
+ "'https://sqs.ap-southeast-2.amazonaws.com/111212121/MyQeueue'"
+ end
+ validated_params
+ end
+
+ def fetch_from_api
+ aws_response = BackendFactory.create(inspec_runner).get_queue_attributes(queue_url: @url, attribute_names: ['All']).attributes
+ @exists = true
+ @visibility_timeout = aws_response['VisibilityTimeout'].to_i
+ @maximum_message_size = aws_response['MaximumMessageSize'].to_i
+ @message_retention_period = aws_response['MessageRetentionPeriod'].to_i
+ @delay_seconds = aws_response['DelaySeconds'].to_i
+ @receive_message_wait_timeout_seconds = aws_response['ReceiveMessageWaitTimeSeconds'].to_i
+
+ # FIFO queues - these attributes only exist for FIFO queues, their presence indicates a FIFO
+ # queue
+ @is_fifo_queue = aws_response['FifoQueue'].nil? ? false: true
+ @content_based_deduplication = aws_response['ContentBasedDeduplication'].nil? ? false: true
+ rescue Aws::SQS::Errors::NonExistentQueue
+ @exists = false
+ end
+
+ # Uses the SDK API to really talk to AWS
+ class Backend
+ class AwsClientApi < AwsBackendBase
+ BackendFactory.set_default_backend(self)
+ self.aws_client_class = Aws::SQS::Client
+
+ def get_queue_attributes(criteria)
+ aws_service_client.get_queue_attributes(criteria)
+ end
+ end
+ end
+end
diff --git a/test/integration/aws/default/build/sqs.tf b/test/integration/aws/default/build/sqs.tf
new file mode 100644
index 000000000..57d718216
--- /dev/null
+++ b/test/integration/aws/default/build/sqs.tf
@@ -0,0 +1,33 @@
+#===========================================================================#
+# SQS QUeue
+#===========================================================================#
+
+# Test fixture:
+# sqs_queue_1 is a non-fifo queue
+# sqs_queue_2 is a fifo queue
+
+
+
+resource "aws_sqs_queue" "sqs_queue_1" {
+ name = "sqs_queue_1"
+ delay_seconds = 0
+ max_message_size = 262144 # 256 KB
+ message_retention_seconds = 345600 # 4 days
+ receive_wait_time_seconds = 2
+ visibility_timeout_seconds = 300 # 5 minutes
+}
+
+output "sqs_queue_1_url" {
+ value = "${aws_sqs_queue.sqs_queue_1.id}"
+}
+
+
+resource "aws_sqs_queue" "sqs_queue_2" {
+ name = "sqs_queue_2.fifo"
+ fifo_queue = true
+ content_based_deduplication = true
+}
+
+output "sqs_queue_2_url" {
+ value = "${aws_sqs_queue.sqs_queue_2.id}"
+}
diff --git a/test/integration/aws/default/verify/controls/aws_sqs_queue.rb b/test/integration/aws/default/verify/controls/aws_sqs_queue.rb
new file mode 100644
index 000000000..c694889c6
--- /dev/null
+++ b/test/integration/aws/default/verify/controls/aws_sqs_queue.rb
@@ -0,0 +1,47 @@
+fixtures = {}
+[
+ 'sqs_queue_1_url',
+ 'sqs_queue_2_url',
+].each do |fixture_name|
+ fixtures[fixture_name] = attribute(
+ fixture_name,
+ default: "default.#{fixture_name}",
+ description: 'See ../build/sqs.tf',
+ )
+end
+
+control 'aws_sqs_queue lookup' do
+
+ sqs_queue1_url = fixtures['sqs_queue_1_url']
+
+ # Search miss
+ sqs_queue_url_non_existent = sqs_queue1_url + "random"
+
+ describe aws_sqs_queue(sqs_queue_url_non_existent) do
+ it { should_not exist }
+ end
+
+ # Search hit
+ describe aws_sqs_queue(sqs_queue1_url) do
+ it { should exist }
+ end
+end
+
+control "aws_sqs_queue properties" do
+ describe aws_sqs_queue(fixtures['sqs_queue_1_url']) do
+ its('delay_seconds') { should be 0 }
+ its('is_fifo_queue') { should be false }
+ its('visibility_timeout') { should be 300 }
+ its('maximum_message_size') { should be 262144 }
+ its('message_retention_period') { should be 345600 }
+ its('receive_message_wait_timeout_seconds') { should be 2 }
+ end
+end
+
+
+control "aws_sqs_queue fifo properties" do
+ describe aws_sqs_queue(fixtures['sqs_queue_2_url']) do
+ its('is_fifo_queue') { should be true }
+ its('content_based_deduplication') { should be true }
+ end
+end
\ No newline at end of file
diff --git a/test/unit/resources/aws_sqs_queue_test.rb b/test/unit/resources/aws_sqs_queue_test.rb
new file mode 100644
index 000000000..874949738
--- /dev/null
+++ b/test/unit/resources/aws_sqs_queue_test.rb
@@ -0,0 +1,126 @@
+require 'helper'
+
+# MSQB = MockSQsBackend
+# Abbreviation not used outside this file
+
+#=============================================================================#
+# Constructor Tests
+#=============================================================================#
+class AwsSqsQueueConstructorTest < Minitest::Test
+ def setup
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::Hit)
+ end
+
+ def test_constructor_some_args_required
+ assert_raises(ArgumentError) { AwsSqsQueue.new }
+ end
+
+ def test_constructor_accepts_scalar_url
+ AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/5195277125796/MyQueue')
+ end
+
+ def test_constructor_accepts_url_as_hash
+ AwsSqsQueue.new(url: 'https://sqs.ap-southeast-2.amazonaws.com/5195277125796/MyQueue')
+ end
+
+ def test_constructor_rejects_unrecognized_resource_params
+ assert_raises(ArgumentError) { AwsSqsQueue.new(beep: 'boop') }
+ end
+
+ def test_constructor_rejects_non_https_url
+ [
+ 'not-even-a-url',
+ 'http://example.com', # http
+ ].each do |example|
+ assert_raises(ArgumentError) { AwsSqsQueue.new(url: example) }
+ end
+ end
+end
+
+#=============================================================================#
+# Search/Recall
+#=============================================================================#
+class AwsSqsQueueRecallTest < Minitest::Test
+ # No setup here - each test needs to explicitly declare
+ # what they want from the backend.
+
+ def test_recall_no_match_is_no_exception
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::Miss)
+ queue = AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/12121/idontexist')
+ refute queue.exists?
+ end
+
+ def test_recall_match_single_result_works
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::Hit)
+ queue = AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/12121/iexist')
+ assert queue.exists?
+ end
+end
+
+#=============================================================================#
+# Properties
+#=============================================================================#
+
+class AwsSqsQueuePropertiesTest < Minitest::Test
+ # No setup here - each test needs to explicitly declare
+ # what they want from the backend.
+
+ #---------------------------------------
+ # confirmed_subscription_count
+ #---------------------------------------
+ def test_visibility_timeout
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::Hit)
+ queue = AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/12121/iexist')
+ assert_equal(300, queue.visibility_timeout)
+ end
+
+ def test_not_fifo_queue
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::Hit)
+ queue = AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/12121/iexist')
+ refute queue.is_fifo_queue
+ end
+
+ def test_fifo_queue
+ AwsSqsQueue::BackendFactory.select(AwsMSQB::FifoQueue)
+ queue = AwsSqsQueue.new('https://sqs.ap-southeast-2.amazonaws.com/12121/iexist')
+ assert queue.is_fifo_queue
+ assert queue.content_based_deduplication
+ end
+end
+
+#=============================================================================#
+# Test Fixtures
+#=============================================================================#
+
+module AwsMSQB
+
+ class Miss < AwsBackendBase
+ def get_queue_attributes(criteria)
+ raise Aws::SQS::Errors::NonExistentQueue.new("No SQS queue with URL #{criteria[:url]}", 'Nope')
+ end
+ end
+
+ class Hit < AwsBackendBase
+ def get_queue_attributes(_criteria)
+ OpenStruct.new({
+ attributes: {
+ "QueueArn" => "arn:aws:sqs:ap-southeast-2:519527721296:MyQueue",
+ "VisibilityTimeout" => 300
+ }
+ })
+ end
+ end
+
+ class FifoQueue < AwsBackendBase
+ def get_queue_attributes(_criteria)
+ OpenStruct.new({
+ attributes: {
+ "QueueArn" => "arn:aws:sqs:ap-southeast-2:519527721296:MyQueue.fifo",
+ "VisibilityTimeout" => 300,
+ "FifoQueue" => true,
+ "ContentBasedDeduplication" => true
+ }
+ })
+ end
+ end
+end
\ No newline at end of file