diff --git a/README.md b/README.md
index ca01c66..5031e43 100644
--- a/README.md
+++ b/README.md
@@ -130,7 +130,13 @@ discover {
       name of the config that was selected by the user.
       */
       Environment = "${config.name}"
-      Service     = "bastion"
+    }
+
+    /*
+    TagsNotEqual can be used to exclude instances with matching tags.
+    */
+    TagsNotEqual {
+      Service = "k8s"
     }
   }
 
diff --git a/ssha/ec2.py b/ssha/ec2.py
index 8c51e56..d60c327 100644
--- a/ssha/ec2.py
+++ b/ssha/ec2.py
@@ -1,5 +1,7 @@
 from __future__ import print_function
 
+import operator
+
 from . import aws, config, errors, ssm
 
 
@@ -42,19 +44,27 @@ def _instance_sort_key(instance):
     return result
 
 
-def _rules_pass(obj, rules):
+def _rules_pass(obj, rules, compare=operator.eq):
 
     for key, expected_value in rules.items():
 
-        if key not in obj:
-            return False
-
         if isinstance(expected_value, dict):
-            nested_rules = expected_value
-            if not _rules_pass(obj[key], nested_rules):
+
+            if key.endswith('NotEqual'):
+                nested_compare = operator.ne
+                key = key[:-len('NotEqual')]
+            else:
+                nested_compare = compare
+
+            nested_rules_passed = _rules_pass(
+                obj=obj.get(key) or {},
+                rules=expected_value,
+                compare=nested_compare,
+            )
+            if not nested_rules_passed:
                 return False
 
-        elif obj[key] != expected_value:
+        elif not compare(obj.get(key), expected_value):
             return False
 
     return True

Exclude instances
The `discover` and `bastion` blocks allow filters on tags and such. It could be useful to exclude instances with certain tags too.
diff --git a/tests/test_ec2.py b/tests/test_ec2.py
new file mode 100644
index 0000000..d44e071
--- /dev/null
+++ b/tests/test_ec2.py
@@ -0,0 +1,49 @@
+import unittest
+
+from ssha import ec2
+
+
+class TestEC2(unittest.TestCase):
+
+    def test_rules_pass(self):
+
+        bastion_instance = {
+            'State': {
+                'Name': 'Running',
+            },
+            'Tags': {
+                'Service': 'bastion',
+            },
+        }
+
+        web_instance = {
+            'State': {
+                'Name': 'Running',
+            },
+            'Tags': {
+                'Service': 'web',
+            },
+        }
+
+        is_bastion = {
+            'State': {
+                'Name': 'Running',
+            },
+            'Tags': {
+                'Service': 'bastion',
+            }
+        }
+
+        is_not_bastion = {
+            'State': {
+                'Name': 'Running',
+            },
+            'TagsNotEqual': {
+                'Service': 'bastion',
+            }
+        }
+
+        self.assertTrue(ec2._rules_pass(bastion_instance, is_bastion))
+        self.assertTrue(ec2._rules_pass(web_instance, is_not_bastion))
+        self.assertFalse(ec2._rules_pass(web_instance, is_bastion))
+        self.assertFalse(ec2._rules_pass(bastion_instance, is_not_bastion))

pip install -e .
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bcrypt==4.3.0
boto3==1.37.23
boto3-session-cache==1.0.2
botocore==1.37.23
cffi==1.17.1
cryptography==44.0.2
exceptiongroup==1.2.2
iniconfig==2.1.0
jmespath==1.0.1
packaging==24.2
paramiko==3.5.1
pluggy==1.5.0
pycparser==2.22
pyhcl==0.4.5
PyNaCl==1.5.0
pytest==8.3.5
python-dateutil==2.9.0.post0
s3transfer==0.11.4
six==1.17.0
-e git+https://github.com/claranet/ssha.git@66de5fc0b726aaf076b57c843f7e7d04dbd9641c#egg=ssha
tomli==2.2.1
urllib3==1.26.20

name: ssha
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bcrypt==4.3.0
      - boto3==1.37.23
      - boto3-session-cache==1.0.2
      - botocore==1.37.23
      - cffi==1.17.1
      - cryptography==44.0.2
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - jmespath==1.0.1
      - packaging==24.2
      - paramiko==3.5.1
      - pluggy==1.5.0
      - pycparser==2.22
      - pyhcl==0.4.5
      - pynacl==1.5.0
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - s3transfer==0.11.4
      - six==1.17.0
      - tomli==2.2.1
      - urllib3==1.26.20
prefix: /opt/conda/envs/ssha

tests/test_ec2.py::TestEC2::test_rules_pass
ssha/ec2.py README.md
ssha/ec2.py README.md