From 1caa71d8870145dbd00e912f9df212cf187f9cc9 Mon Sep 17 00:00:00 2001 From: "Sebastian Kirsch (@skirsch79)" Date: Thu, 19 Dec 2019 15:21:09 +0100 Subject: [PATCH] Pick up AWS credentials from ENV (#1310) * Pick up AWS credentials from ENV https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html * Rework AWS authentication part of the documentation * Mention change --- doc/changelog.md | 1 + src/main/asciidoc/inc/_authentication.adoc | 10 +++--- .../maven/docker/util/AuthConfigFactory.java | 24 +++++++++++++ .../docker/util/AuthConfigFactoryTest.java | 35 +++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 2ef61508d..6f4b8ee78 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -13,6 +13,7 @@ - Allow killing and removing all spawned containers (#1182) - Deprecated "authToken" for ECR authentication in favor of "auth" (#1286) - Allow overriding of existing image in creation of temporary one with same tag before push ([#838](https://github.com/fabric8io/docker-maven-plugin/issues/838)) + - Pick up AWS credentials from ENV variables (#1310) * **0.31.0** (2019-08-10) - Fix test cases on Windows ([#1220](https://github.com/fabric8io/docker-maven-plugin/issues/1220)) diff --git a/src/main/asciidoc/inc/_authentication.adoc b/src/main/asciidoc/inc/_authentication.adoc index a5cea8b65..bc17daf49 100644 --- a/src/main/asciidoc/inc/_authentication.adoc +++ b/src/main/asciidoc/inc/_authentication.adoc @@ -186,8 +186,8 @@ Use the IAM *Access key ID* as the username and the *Secret access key* as the p In case you're using temporary security credentials provided by the AWS Security Token Service (AWS STS), you have to provide the *security token* as well. To do so, either specify the `docker.auth` system property or provide an `` element alongside username & password in the `authConfig`. -In case you are running on an EC2 instance OR ECS with fargate deployment (OR ECS with EC2 with ECS_AWSVPC_BLOCK_IMDS as "true") that has an appropriate IAM role assigned -(e.g. a role that grants the AWS built-in policy _AmazonEC2ContainerRegistryPowerUser_) -authentication information doesn't need to be provided at all. Instead the instance -meta-data service or task metadata endpoint in case of ECS is queried for temporary access credentials supplied by the -assigned role. +d-m-p will attempt to read AWS credentials from some well-known spots in case there is no explicit configuration: +* it will pick up ENV variables link:https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html[as documented for the AWS CLI] +* it will pick up temporary credentials of link:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html[the IAM role of an EC2 instance] +* it will pick up temporary credentials of link:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html[the IAM role of a fargate task (OR ECS with EC2 with ECS_AWSVPC_BLOCK_IMDS as "true")] +If any of these authentication information is accessible, it will be used. diff --git a/src/main/java/io/fabric8/maven/docker/util/AuthConfigFactory.java b/src/main/java/io/fabric8/maven/docker/util/AuthConfigFactory.java index 5648f63e6..92987b77c 100644 --- a/src/main/java/io/fabric8/maven/docker/util/AuthConfigFactory.java +++ b/src/main/java/io/fabric8/maven/docker/util/AuthConfigFactory.java @@ -227,6 +227,12 @@ private AuthConfig createStandardAuthConfig(boolean isPush, Map authConfigMap, S // check EC2 instance role if registry is ECR if (EcrExtendedAuth.isAwsRegistry(registry)) { + ret = getAuthConfigFromAwsEnvironmentVariables(); + if (ret != null) { + log.debug("AuthConfig: AWS credentials from ENV variables"); + return ret; + } + try { ret = getAuthConfigFromEC2InstanceRole(); } catch (ConnectTimeoutException ex) { @@ -259,6 +265,24 @@ private AuthConfig createStandardAuthConfig(boolean isPush, Map authConfigMap, S return null; } + /** + * Try using the AWS credentials provided via ENV variables. + * See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html + */ + private AuthConfig getAuthConfigFromAwsEnvironmentVariables() { + String accessKeyId = System.getenv("AWS_ACCESS_KEY_ID"); + if (accessKeyId == null) { + log.debug("System environment not set for variable AWS_ACCESS_KEY_ID, no AWS credentials found"); + return null; + } + String secretAccessKey = System.getenv("AWS_SECRET_ACCESS_KEY"); + if (secretAccessKey == null) { + log.warn("System environment set for variable AWS_ACCESS_KEY_ID, but NOT for variable AWS_SECRET_ACCESS_KEY!"); + return null; + } + return new AuthConfig(accessKeyId, secretAccessKey, "none", System.getenv("AWS_SESSION_TOKEN")); + } + // =================================================================================================== diff --git a/src/test/java/io/fabric8/maven/docker/util/AuthConfigFactoryTest.java b/src/test/java/io/fabric8/maven/docker/util/AuthConfigFactoryTest.java index 3b7f8461a..1b4e5276f 100644 --- a/src/test/java/io/fabric8/maven/docker/util/AuthConfigFactoryTest.java +++ b/src/test/java/io/fabric8/maven/docker/util/AuthConfigFactoryTest.java @@ -550,6 +550,41 @@ public void fargateTaskRole() throws IOException, MojoExecutionException { verifyAuthConfig(authConfig, accessKeyId, secretAccessKey, null, sessionToken); } + @Test + public void awsTemporaryCredentialsArePickedUpFromEnvironment() throws MojoExecutionException { + String accessKeyId = randomUUID().toString(); + String secretAccessKey = randomUUID().toString(); + String sessionToken = randomUUID().toString(); + environmentVariables.set("AWS_ACCESS_KEY_ID", accessKeyId); + environmentVariables.set("AWS_SECRET_ACCESS_KEY", secretAccessKey); + environmentVariables.set("AWS_SESSION_TOKEN", sessionToken); + + AuthConfig authConfig = factory.createAuthConfig(false, true, null, settings, "user", ECR_NAME); + + verifyAuthConfig(authConfig, accessKeyId, secretAccessKey, null, sessionToken); + } + + @Test + public void awsStaticCredentialsArePickedUpFromEnvironment() throws MojoExecutionException { + String accessKeyId = randomUUID().toString(); + String secretAccessKey = randomUUID().toString(); + environmentVariables.set("AWS_ACCESS_KEY_ID", accessKeyId); + environmentVariables.set("AWS_SECRET_ACCESS_KEY", secretAccessKey); + + AuthConfig authConfig = factory.createAuthConfig(false, true, null, settings, "user", ECR_NAME); + + verifyAuthConfig(authConfig, accessKeyId, secretAccessKey, null, null); + } + + @Test + public void incompleteAwsCredentialsAreIgnored() throws MojoExecutionException { + environmentVariables.set("AWS_ACCESS_KEY_ID", randomUUID().toString()); + + AuthConfig authConfig = factory.createAuthConfig(false, true, null, settings, "user", ECR_NAME); + + assertNull(authConfig); + } + private void setupServers() { new Expectations() {{ List servers = new ArrayList<>();