diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.17.1.0...main)
+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.17.0.0...main)
+
+## [v1.18.0.0](https://github.com/freckle/freckle-app/compare/v1.17.1.0...v1.18.0.0)
+
+- Drop deprecated hs-opentelemetry-datadog functionality
+- Remove AWS XRay module
 
 ## [v1.17.1.0](https://github.com/freckle/freckle-app/compare/v1.17.0.0...v1.17.1.0)
 
diff --git a/freckle-app.cabal b/freckle-app.cabal
--- a/freckle-app.cabal
+++ b/freckle-app.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.18
 name:               freckle-app
-version:            1.17.1.0
+version:            1.18.0.0
 license:            MIT
 license-file:       LICENSE
 maintainer:         Freckle Education
@@ -29,7 +29,6 @@
         Freckle.App.Bugsnag.SqlError
         Freckle.App.Csv
         Freckle.App.Database
-        Freckle.App.Database.XRay
         Freckle.App.Dotenv
         Freckle.App.Ecs
         Freckle.App.Env
@@ -79,7 +78,6 @@
         Freckle.App.Yesod
         Freckle.App.Yesod.Routes
         Network.Wai.Middleware.Cors
-        Network.Wai.Middleware.OpenTelemetry
         Network.Wai.Middleware.Stats
         Yesod.Core.Lens
 
@@ -111,8 +109,6 @@
         annotated-exception >=0.2.0.4,
         autodocodec >=0.2.0.3,
         autodocodec-openapi3 >=0.2.1.1,
-        aws-xray-client-persistent >=0.1.0.5,
-        aws-xray-client-wai >=0.1.0.2,
         base >=4.16.4.0 && <5,
         bcp47 >=0.2.0.6,
         bugsnag >=1.1.0.0,
@@ -138,12 +134,11 @@
         hs-opentelemetry-api >=0.1.0.0,
         hs-opentelemetry-instrumentation-persistent >=0.1.0.0,
         hs-opentelemetry-instrumentation-wai >=0.1.0.0,
-        hs-opentelemetry-propagator-datadog >=0.0.0.0,
         hs-opentelemetry-sdk >=0.0.3.6,
         hspec >=2.8.1,
         hspec-core >=2.8.1,
         hspec-expectations-lifted >=0.10.0,
-        hspec-junit-formatter >=1.1.0.1,
+        hspec-junit-formatter >=1.1.1.0,
         http-client >=0.7.13.1,
         http-conduit >=2.3.5,
         http-link-header >=1.2.1,
@@ -180,7 +175,6 @@
         transformers-base >=0.4.6,
         typed-process >=0.2.11.0,
         unliftio >=0.2.25.0,
-        unliftio-core >=0.2.1.0,
         unordered-containers >=0.2.19.1,
         vector >=0.12.3.1,
         wai >=3.2.3,
@@ -277,7 +271,7 @@
         errors >=2.3.0,
         freckle-app,
         hs-opentelemetry-api >=0.1.0.0,
-        hspec >=2.9.7,
+        hspec >=2.10.10,
         hspec-expectations-json >=1.0.0.7,
         hspec-expectations-lifted >=0.10.0,
         http-types >=0.12.3,
diff --git a/library/Freckle/App.hs b/library/Freckle/App.hs
--- a/library/Freckle/App.hs
+++ b/library/Freckle/App.hs
@@ -188,7 +188,6 @@
 import Control.Monad.Reader
 import Control.Monad.Trans.Resource (MonadResource, ResourceT, runResourceT)
 import Freckle.App.Database
-import qualified Freckle.App.Database.XRay as XRay
 import Freckle.App.Http (MonadHttp (..))
 import Freckle.App.OpenTelemetry
 import Freckle.App.OpenTelemetry.Context
@@ -245,9 +244,6 @@
 
 instance (Monad m, HasTracer app) => MonadTracer (AppT app m) where
   getTracer = view tracerL
-
-instance Applicative m => XRay.MonadTracer (AppT app m) where
-  getVaultData = pure Nothing
 
 instance
   (MonadUnliftIO m, HasSqlPool app, HasStatsClient app, HasTracer app)
diff --git a/library/Freckle/App/Database/XRay.hs b/library/Freckle/App/Database/XRay.hs
deleted file mode 100644
--- a/library/Freckle/App/Database/XRay.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-# LANGUAGE ApplicativeDo #-}
-{-# LANGUAGE TypeOperators #-}
-
--- | Legacy version of "Freckle.App.Database" that still uses XRay
-module Freckle.App.Database.XRay
-  ( -- * Running transactions
-    MonadSqlTx (..)
-  , runDB
-  , runDBSimple
-
-    -- * Running queries
-  , SqlBackend
-  , HasSqlBackend (..)
-  , MonadSqlBackend (..)
-  , liftSql
-
-    -- * Telemetry
-  , MonadTracer (..)
-  , HasStatsClient
-
-    -- * Connection pools
-  , HasSqlPool (..)
-  , SqlPool
-  , makePostgresPool
-  , makePostgresPoolWith
-
-    -- * Setup
-  , PostgresConnectionConf (..)
-  , PostgresPasswordSource (..)
-  , PostgresPassword (..)
-  , PostgresStatementTimeout
-  , postgresStatementTimeoutMilliseconds
-  , envParseDatabaseConf
-  , envPostgresPasswordSource
-  ) where
-
-import Freckle.App.Prelude
-
-import Control.Monad.IO.Unlift (MonadUnliftIO (..))
-import Control.Monad.Reader
-import Data.Pool
-import Database.Persist.Postgresql (SqlPersistT, runSqlConn, runSqlPool)
-import Freckle.App.Database hiding (MonadTracer, runDB)
-import qualified Freckle.App.Stats as Stats
-import Network.AWS.XRayClient.Persistent
-import Network.AWS.XRayClient.WAI
-  ( XRayVaultData
-  , atomicallyAddVaultDataSubsegment
-  , traceXRaySubsegment'
-  , vaultDataFromRequest
-  , xrayVaultDataStdGen
-  )
-import Yesod.Core (HandlerFor, waiRequest)
-
--- | Class for reading 'XRayVaultData'
---
--- This is named the same as the OpenTelemetry class we'll use once we move to
--- that tracing system
-class MonadTracer m where
-  getVaultData :: m (Maybe XRayVaultData)
-
-instance MonadTracer (HandlerFor app) where
-  getVaultData = vaultDataFromRequest <$> waiRequest
-
--- | Run a Database action with connection stats and tracing
-runDB
-  :: ( MonadUnliftIO m
-     , MonadTracer m
-     , MonadReader app m
-     , HasSqlPool app
-     , HasStatsClient app
-     )
-  => SqlPersistT m a
-  -> m a
-runDB action = do
-  pool <- asks getSqlPool
-  mVaultData <- getVaultData
-  Stats.withGauge Stats.dbConnections $
-    maybe runSqlPool (runSqlPoolXRay "runDB") mVaultData action pool
-
--- | @'runSqlPool'@ but with XRay tracing
-runSqlPoolXRay
-  :: (backend ~ SqlBackend, MonadUnliftIO m)
-  => Text
-  -- ^ Subsegment name
-  --
-  -- The top-level subsegment will be named @\"<this> runSqlPool\"@ and the,
-  -- with a lower-level subsegment named @\"<this> query\"@.
-  -> XRayVaultData
-  -- ^ Vault data to trace with
-  -> ReaderT backend m a
-  -> Pool backend
-  -> m a
-runSqlPoolXRay name vaultData action pool =
-  traceXRaySubsegment' vaultData (name <> " runSqlPool") id $
-    withRunInIO $
-      \run -> withResource pool $ \backend -> do
-        let
-          sendTrace = atomicallyAddVaultDataSubsegment vaultData
-          stdGenIORef = xrayVaultDataStdGen vaultData
-          subsegmentName = name <> " query"
-        run . runSqlConn action
-          =<< liftIO
-            (xraySqlBackend sendTrace stdGenIORef subsegmentName backend)
diff --git a/library/Freckle/App/OpenTelemetry.hs b/library/Freckle/App/OpenTelemetry.hs
--- a/library/Freckle/App/OpenTelemetry.hs
+++ b/library/Freckle/App/OpenTelemetry.hs
@@ -39,9 +39,7 @@
   , consumerSpanArguments
 
     -- * Querying
-  , withTraceIdContext
   , getCurrentTraceId
-  , getCurrentTraceIdAsDatadog
   , getCurrentSpanContext
 
     -- * Ids
@@ -68,18 +66,12 @@
 
 import Freckle.App.Prelude
 
-import Blammo.Logging (withThreadContext, (.=))
-import Control.Monad.Catch (MonadMask)
 import Data.ByteString (ByteString)
 import qualified Data.Text as T
 import Data.Text.Encoding (decodeUtf8With)
 import Data.Text.Encoding.Error (lenientDecode)
-import Data.Word (Word64)
 import OpenTelemetry.Context (lookupSpan)
 import OpenTelemetry.Context.ThreadLocal (getContext)
-import OpenTelemetry.Propagator.Datadog
-  ( convertOpenTelemetryTraceIdToDatadogTraceId
-  )
 import OpenTelemetry.Trace hiding (inSpan)
 import OpenTelemetry.Trace.Core (getSpanContext)
 import qualified OpenTelemetry.Trace.Core as Trace (SpanContext (..))
@@ -135,11 +127,6 @@
 getCurrentTraceId :: MonadIO m => m (Maybe TraceId)
 getCurrentTraceId = fmap Trace.traceId <$> getCurrentSpanContext
 
-getCurrentTraceIdAsDatadog :: MonadIO m => m (Maybe Word64)
-getCurrentTraceIdAsDatadog =
-  fmap convertOpenTelemetryTraceIdToDatadogTraceId <$> getCurrentTraceId
-{-# DEPRECATED getCurrentTraceIdAsDatadog "Datadog can operate with Base16 ids" #-}
-
 getCurrentSpanContext :: MonadIO m => m (Maybe SpanContext)
 getCurrentSpanContext = withCurrentSpan getSpanContext
 
@@ -150,12 +137,6 @@
 withCurrentSpan f = do
   mSpan <- lookupSpan <$> getContext
   traverse f mSpan
-
-withTraceIdContext :: (MonadIO m, MonadMask m) => m a -> m a
-withTraceIdContext f = do
-  mTraceId <- getCurrentTraceIdAsDatadog
-  maybe f (\traceId -> withThreadContext ["trace_id" .= traceId] f) mTraceId
-{-# DEPRECATED withTraceIdContext "Use Freckle.App.OpenTelemetry.ThreadContext" #-}
 
 traceIdToHex :: TraceId -> Text
 traceIdToHex = traceIdBaseEncodedText Base16
diff --git a/library/Freckle/App/Test.hs b/library/Freckle/App/Test.hs
--- a/library/Freckle/App/Test.hs
+++ b/library/Freckle/App/Test.hs
@@ -50,7 +50,6 @@
   , MonadSqlTx (..)
   , runDB
   )
-import qualified Freckle.App.Database.XRay as XRay
 import qualified Freckle.App.Dotenv as Dotenv
 import qualified Freckle.App.Exception.MonadThrow as MonadThrow
 import Freckle.App.OpenTelemetry
@@ -119,9 +118,6 @@
 
 instance HasTracer app => MonadTracer (AppExample app) where
   getTracer = view tracerL
-
-instance XRay.MonadTracer (AppExample app) where
-  getVaultData = pure Nothing
 
 instance
   (HasSqlPool app, HasStatsClient app, HasTracer app)
diff --git a/library/Freckle/App/Test/Hspec/Runner.hs b/library/Freckle/App/Test/Hspec/Runner.hs
--- a/library/Freckle/App/Test/Hspec/Runner.hs
+++ b/library/Freckle/App/Test/Hspec/Runner.hs
@@ -11,17 +11,17 @@
 import Control.Monad.Trans.Maybe (MaybeT (MaybeT), runMaybeT)
 import Data.List (isInfixOf)
 import System.Environment (getArgs, lookupEnv)
-import Test.Hspec (Spec)
-import Test.Hspec.JUnit
-  ( configWithJUnit
-  , setJUnitConfigOutputFile
+import Test.Hspec (Spec, runIO)
+import Test.Hspec.JUnit.Config
+  ( setJUnitConfigOutputFile
   , setJUnitConfigSourcePathPrefix
   )
-import Test.Hspec.JUnit.Config.Env (envJUnitConfig, envJUnitEnabled)
+import Test.Hspec.JUnit.Config.Env (envJUnitConfig)
+import qualified Test.Hspec.JUnit.Formatter as JUnit (add)
+import qualified Test.Hspec.JUnit.Formatter.Env as JUnit (whenEnabled)
 import Test.Hspec.Runner
   ( Config
   , Path
-  , Summary
   , configConcurrentJobs
   , configSkipPredicate
   , defaultConfig
@@ -66,17 +66,15 @@
  where
   load = flip readConfig
   runner filename changeConfig =
-    (spec `runWithJUnit` ("/tmp/junit", filename)) . changeConfig
+    runSpec (addJUnit "/tmp/junit" filename spec) . changeConfig
   noConcurrency x = x {configConcurrentJobs = Just 1}
+  runSpec = flip hspecWithResult
 
-runWithJUnit :: Spec -> (FilePath, String) -> Config -> IO Summary
-runWithJUnit spec (path, name) config = do
-  junitEnabled <- envJUnitEnabled
-  baseJUnitConfig <- envJUnitConfig
-  let modify = if junitEnabled then configWithJUnit $ withOverride baseJUnitConfig else id
-  spec `runSpec` modify config
+addJUnit :: FilePath -> String -> Spec -> Spec
+addJUnit path name spec = do
+  junitConfig <- runIO $ withOverride <$> envJUnitConfig
+  JUnit.whenEnabled (JUnit.add junitConfig) spec
  where
-  runSpec = flip hspecWithResult
   filePath = path <> "/" <> name <> "/test_results.xml"
   withOverride =
     setJUnitConfigSourcePathPrefix name . setJUnitConfigOutputFile filePath
@@ -116,4 +114,4 @@
 isolatedTests = ("ISOLATED" `isInfixOf`) . snd
 
 anys :: [a -> Bool] -> a -> Bool
-anys xs a = or $ fmap (\f -> f a) xs
+anys xs a = any ($ a) xs
diff --git a/library/Freckle/App/Wai.hs b/library/Freckle/App/Wai.hs
--- a/library/Freckle/App/Wai.hs
+++ b/library/Freckle/App/Wai.hs
@@ -26,8 +26,8 @@
 import Network.Wai.Middleware.AddHeaders
 import Network.Wai.Middleware.Cors
 import Network.Wai.Middleware.Logging
-import Network.Wai.Middleware.OpenTelemetry
 import Network.Wai.Middleware.Stats
+import OpenTelemetry.Instrumentation.Wai
 
 -- | Middleware that adds header to disable all caching
 noCacheMiddleware :: Middleware
diff --git a/library/Network/Wai/Middleware/OpenTelemetry.hs b/library/Network/Wai/Middleware/OpenTelemetry.hs
deleted file mode 100644
--- a/library/Network/Wai/Middleware/OpenTelemetry.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-# OPTIONS_GHC -Wno-deprecations #-}
-
-module Network.Wai.Middleware.OpenTelemetry
-  ( newOpenTelemetryWaiMiddleware
-  , openTelemetryMiddleware
-  ) where
-
-import Freckle.App.Prelude
-
-import qualified Data.ByteString.Char8 as BS8
-import Freckle.App.OpenTelemetry
-import Network.Wai
-import Network.Wai.Middleware.AddHeaders
-import qualified OpenTelemetry.Instrumentation.Wai as Trace
-
-newOpenTelemetryWaiMiddleware :: IO Middleware
-newOpenTelemetryWaiMiddleware = do
-  otel <- Trace.newOpenTelemetryWaiMiddleware
-  pure $ otel . openTelemetryMiddleware
-{-# DEPRECATED
-  newOpenTelemetryWaiMiddleware
-  "Use OpenTelemetry.Instrumentation.Wai.newOpenTelemetryWaiMiddleware"
-  #-}
-
--- | Add 'TraceId' information to context and responses
---
--- - Adds @trace_id@ to the logging context
--- - Adds @X-Datadog-TraceId@ to response headers
---
--- This is added automatically by our 'newOpenTelemetryWaiMiddleware'.
-openTelemetryMiddleware :: Middleware
-openTelemetryMiddleware app request respond =
-  withTraceIdContext $ addTraceIdHeader app request respond
-{-# DEPRECATED openTelemetryMiddleware "Use addThreadContextFromTracing" #-}
-
-addTraceIdHeader :: Middleware
-addTraceIdHeader app request respond = do
-  mTraceId <- getCurrentTraceIdAsDatadog
-  maybe id addHeader mTraceId app request respond
- where
-  addHeader traceId =
-    addHeaders [("X-Datadog-Trace-Id", BS8.pack $ show traceId)]
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: freckle-app
-version: 1.17.1.0
+version: 1.18.0.0
 maintainer: Freckle Education
 category: Utils
 github: freckle/freckle-app
@@ -76,8 +76,6 @@
     - autodocodec-openapi3
     - aeson
     - annotated-exception
-    - aws-xray-client-persistent
-    - aws-xray-client-wai
     - bcp47
     - bugsnag >= 1.1.0.0 # Network.Bugsnag.MetaData
     - bytestring
@@ -102,12 +100,11 @@
     - hs-opentelemetry-api
     - hs-opentelemetry-instrumentation-persistent
     - hs-opentelemetry-instrumentation-wai
-    - hs-opentelemetry-propagator-datadog
     - hs-opentelemetry-sdk
     - hspec >= 2.8.1
     - hspec-core >= 2.8.1
     - hspec-expectations-lifted
-    - hspec-junit-formatter >= 1.1.0.1
+    - hspec-junit-formatter >= 1.1.1.0 # Test.Hspec.JUnit.Formatter
     - http-client
     - http-conduit >= 2.3.5 # addToRequestQueryString
     - http-link-header
@@ -144,7 +141,6 @@
     - transformers-base
     - typed-process
     - unliftio
-    - unliftio-core
     - unordered-containers
     - vector
     - wai
