diff --git a/build.gradle b/build.gradle
index 5aa531a97c5a5..797638357542f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -46,6 +46,7 @@ apply from: 'gradle/ide.gradle'
 apply from: 'gradle/forbidden-dependencies.gradle'
 apply from: 'gradle/formatting.gradle'
 apply from: 'gradle/local-distribution.gradle'
+apply from: 'gradle/fips.gradle'
 
 // common maven publishing configuration
 allprojects {
diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
index b17d6e2749807..37291f6594e0b 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
@@ -19,33 +19,15 @@
 package org.elasticsearch.gradle
 
 import groovy.transform.CompileStatic
-import org.apache.commons.io.IOUtils
 import org.elasticsearch.gradle.info.GlobalBuildInfoPlugin
 import org.elasticsearch.gradle.precommit.PrecommitTasks
-import org.elasticsearch.gradle.test.ErrorReportingTestListener
-import org.elasticsearch.gradle.testclusters.ElasticsearchCluster
-import org.elasticsearch.gradle.testclusters.TestClustersPlugin
-import org.elasticsearch.gradle.util.GradleUtils
-import org.gradle.api.*
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.artifacts.Dependency
-import org.gradle.api.artifacts.ModuleDependency
-import org.gradle.api.artifacts.ProjectDependency
-import org.gradle.api.artifacts.dsl.RepositoryHandler
-import org.gradle.api.artifacts.repositories.ExclusiveContentRepository
-import org.gradle.api.artifacts.repositories.IvyArtifactRepository
-import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
-import org.gradle.api.artifacts.repositories.MavenArtifactRepository
-import org.gradle.api.credentials.HttpHeaderCredentials
-import org.gradle.api.execution.TaskActionListener
+import org.gradle.api.GradleException
+import org.gradle.api.InvalidUserDataException
+import org.gradle.api.Plugin
+import org.gradle.api.Project
 import org.gradle.api.file.CopySpec
 import org.gradle.api.plugins.ExtraPropertiesExtension
-import org.gradle.api.plugins.JavaPlugin
 import org.gradle.api.tasks.bundling.Jar
-import org.gradle.api.tasks.testing.Test
-import org.gradle.util.GradleVersion
-
-import java.nio.charset.StandardCharsets
 
 /**
  * Encapsulates build configuration for elasticsearch projects.
@@ -72,55 +54,6 @@ class BuildPlugin implements Plugin<Project> {
 
         project.extensions.getByType(ExtraPropertiesExtension).set('versions', VersionProperties.versions)
         PrecommitTasks.create(project, true)
-        configureFips140(project)
-    }
-
-    static void configureFips140(Project project) {
-        // Common config when running with a FIPS-140 runtime JVM
-        if (inFipsJvm()) {
-            ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') as ExportElasticsearchBuildResourcesTask
-            File securityProperties = buildResources.copy("fips_java.security")
-            File securityPolicy = buildResources.copy("fips_java.policy")
-            File bcfksKeystore = buildResources.copy("cacerts.bcfks")
-            // This configuration can be removed once system modules are available
-            GradleUtils.maybeCreate(project.configurations, 'extraJars') {
-                project.dependencies.add('extraJars', "org.bouncycastle:bc-fips:1.0.1")
-                project.dependencies.add('extraJars', "org.bouncycastle:bctls-fips:1.0.9")
-            }
-            project.pluginManager.withPlugin("elasticsearch.testclusters") {
-                NamedDomainObjectContainer<ElasticsearchCluster> testClusters = project.extensions.findByName(TestClustersPlugin.EXTENSION_NAME) as NamedDomainObjectContainer<ElasticsearchCluster>
-                testClusters.all { ElasticsearchCluster cluster ->
-                    for (File dep : project.getConfigurations().getByName("extraJars").getFiles()){
-                        cluster.extraJarFile(dep)
-                    }
-                    cluster.extraConfigFile("fips_java.security", securityProperties)
-                    cluster.extraConfigFile("fips_java.policy", securityPolicy)
-                    cluster.extraConfigFile("cacerts.bcfks", bcfksKeystore)
-                    cluster.systemProperty('java.security.properties', '=${ES_PATH_CONF}/fips_java.security')
-                    cluster.systemProperty('java.security.policy', '=${ES_PATH_CONF}/fips_java.policy')
-                    cluster.systemProperty('javax.net.ssl.trustStore', '${ES_PATH_CONF}/cacerts.bcfks')
-                    cluster.systemProperty('javax.net.ssl.trustStorePassword', 'password')
-                    cluster.systemProperty('javax.net.ssl.keyStorePassword', 'password')
-                    cluster.systemProperty('javax.net.ssl.keyStoreType', 'BCFKS')
-                }
-            }
-            project.tasks.withType(Test).configureEach { Test task ->
-                task.dependsOn(buildResources)
-                task.systemProperty('javax.net.ssl.trustStorePassword', 'password')
-                task.systemProperty('javax.net.ssl.keyStorePassword', 'password')
-                task.systemProperty('javax.net.ssl.trustStoreType', 'BCFKS')
-                // Using the key==value format to override default JVM security settings and policy
-                // see also: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html
-                task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", securityProperties.toString()))
-                task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", securityPolicy.toString()))
-                task.systemProperty('javax.net.ssl.trustStore', bcfksKeystore.toString())
-            }
-
-        }
-    }
-
-    private static inFipsJvm(){
-        return Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
     }
 
     static void configureLicenseAndNotice(Project project) {
diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy
index c4bf0e4db1d4c..a35d01a4bdac0 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy
@@ -65,7 +65,6 @@ class StandaloneRestTestPlugin implements Plugin<Project> {
         ElasticsearchJavaPlugin.configureRepositories(project)
         ElasticsearchJavaPlugin.configureTestTasks(project)
         ElasticsearchJavaPlugin.configureInputNormalization(project)
-        BuildPlugin.configureFips140(project)
         ElasticsearchJavaPlugin.configureCompile(project)
 
         project.extensions.getByType(JavaPluginExtension).sourceCompatibility = BuildParams.minimumRuntimeVersion
diff --git a/gradle/fips.gradle b/gradle/fips.gradle
new file mode 100644
index 0000000000000..b497393de5600
--- /dev/null
+++ b/gradle/fips.gradle
@@ -0,0 +1,56 @@
+import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask
+import org.elasticsearch.gradle.info.BuildParams
+import org.elasticsearch.gradle.testclusters.ElasticsearchCluster
+import org.elasticsearch.gradle.testclusters.ElasticsearchCluster
+
+// Common config when running with a FIPS-140 runtime JVM
+if (BuildParams.inFipsJvm) {
+  allprojects {
+    File fipsResourcesDir = new File(project.buildDir, 'fips-resources')
+    File fipsSecurity = new File(fipsResourcesDir, 'fips_java.security')
+    File fipsPolicy = new File(fipsResourcesDir, 'fips_java.policy')
+    File fipsTrustStore = new File(fipsResourcesDir, 'cacerts.bcfks')
+    project.pluginManager.withPlugin('elasticsearch.java') {
+      TaskProvider<ExportElasticsearchBuildResourcesTask> fipsResourcesTask = project.tasks.register('fipsResources', ExportElasticsearchBuildResourcesTask)
+      fipsResourcesTask.configure {
+        outputDir = fipsResourcesDir
+        copy 'fips_java.security'
+        copy 'fips_java.policy'
+        copy 'cacerts.bcfks'
+      }
+      // This configuration can be removed once system modules are available
+      configurations.create('extraFipsJars')
+      dependencies {
+        extraFipsJars 'org.bouncycastle:bc-fips:1.0.1'
+        extraFipsJars 'org.bouncycastle:bctls-fips:1.0.9'
+      }
+      pluginManager.withPlugin("elasticsearch.testclusters") {
+        testClusters.all {
+          for (File dep : project.configurations.extraFipsJars.files) {
+            extraJarFile dep
+          }
+          extraConfigFile "fips_java.security", fipsSecurity
+          extraConfigFile "fips_java.policy", fipsPolicy
+          extraConfigFile "cacerts.bcfks", fipsTrustStore
+          systemProperty 'java.security.properties', '=${ES_PATH_CONF}/fips_java.security'
+          systemProperty 'java.security.policy', '=${ES_PATH_CONF}/fips_java.policy'
+          systemProperty 'javax.net.ssl.trustStore', '${ES_PATH_CONF}/cacerts.bcfks'
+          systemProperty 'javax.net.ssl.trustStorePassword', 'password'
+          systemProperty 'javax.net.ssl.keyStorePassword', 'password'
+          systemProperty 'javax.net.ssl.keyStoreType', 'BCFKS'
+        }
+      }
+      project.tasks.withType(Test).configureEach { Test task ->
+        task.dependsOn('fipsResources')
+        task.systemProperty('javax.net.ssl.trustStorePassword', 'password')
+        task.systemProperty('javax.net.ssl.keyStorePassword', 'password')
+        task.systemProperty('javax.net.ssl.trustStoreType', 'BCFKS')
+        // Using the key==value format to override default JVM security settings and policy
+        // see also: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html
+        task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", fipsSecurity))
+        task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", fipsPolicy))
+        task.systemProperty('javax.net.ssl.trustStore', fipsTrustStore)
+      }
+    }
+  }
+}