Use AWS CodeArtifact in your project

CodeArtifact

Why CodeArtifact

You should have the experience to create the in-house libraries and integrate them with other projects by either using the multi-module development or publishing them as the AAR files for usage. Here comes another great option from AWS, you can use the CodeArtifact to host your local Maven repositories.

What’s the pain point

The pain point of using CodeArtifact is that the authentication token will be expired every 12 hours. So, you would need to update the token every day for syncing the latest libraries from the CodeArtifact. I have to say this is quite annoying for the Devs. Is there any better way to solve this issue? Yes, thanks Clarity for developing a Gradle plugin to solve this issue. Here are the steps for integrating this plugin with CodeArtifact.

Basic setup - AWS CLI tool installation

You have to install the AWS CLI tool and set up the access key id and secret key string.

1
aws configure

And then input your region, output format, and the access key config. After that, check if everything is good.

1
aws configure list

If you can see the configuration showing correctly, you are ready to go to the next step. Otherwise, please the related configuration before setting up the plugin.

Plugin setup

There are four ways to set up your AWS profile for this plugin.

  1. Set the AWS_PROFILE environment variable with the selected profile name.

  2. Set the CODEARTIFACT_PROFILE environment variable with the selected profile name.

  3. Set the profile using a system property in the gradle.properties.

    1
    systemProp.codeartifact.profile=[your_profile_name]
  4. Add the profile name to the repository URL as a query parameter.

    1
    2
    3
    4
    5
    repositories {
    maven {
    url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/?profile=[your_profile_name]'
    }
    }

After the profile setup ready, you now need to update your build.gradle fiile (project level), please check the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
plugins {  
// Automatically get BuildArtifact token
id 'maven-publish'
id 'ai.clarity.codeartifact' version '0.0.12'
}

allprojects {
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}


publishing {
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}
}
}

After this setting, you are ready for happy coding now!

Integrate with the AWS CodePipeline

If you use the above setting locally, you should be good and worry about nothing. What if you wanted to use it with your CodePipeline? You will need to modify the setting and make it work as expected.

Update your buildspec.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: 0.2  
env:
parameter-store:
ACCESS_KEY_ID: /CodeBuild/access_key_id
SECRET_ACCESS_KEY: /CodeBuild/secret_access_key

phases:
build:
commands:
- echo "Start building the project"
- curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
- unzip awscli-bundle.zip
- ./awscli-bundle/install -b ~/bin/aws
- aws configure set region "your_aws_region"
- aws configure set output "your_wanted_format"
- aws configure set aws_access_key_id $ACCESS_KEY_ID
- aws configure set aws_secret_access_key $SECRET_ACCESS_KEY
- aws configure list
- ./gradlew build

post_build:
commands:
- echo "Cleaning the environment variables"
- aws configure set region ""
- aws configure set output ""
- aws configure set aws_access_key_id ""
- aws configure set aws_secret_access_key ""

You will need to define your AWS profile before building the project. I recommend that you store your access_key_id and secret_access_key into the AWS system manager instead of using them as plaintext.

Update your build.gradle

When you integrate this with CodePipeline, you would see that the 401 authentication error said that you could not access the Maven repository. It’s because even though you use this plugin to get the auth token for those in-house CodeArtifact libraries, Gradle might access those repositories before invoking the plugin to get the token. So there are two ways to solve this issue.

  • Leverage the init.gradle to get the token in the very beginning.
  • Update the build.gradle to get the authentication token if you can’t access the profile.

The second way is much easier. Let’s see how to use it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
allprojects {   
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
credentials {
def getToken = "aws codeartifact get-authorization-token --domain your_domain_id --domain-owner your_account_id --query authorizationToken --output text"
def profile = System.env.CODEARTIFACT_PROFILE
username "aws"
password profile == null ?
getToken.execute().text :
"$getToken --profile $profile".execute().text
}
}
}
}

We will need to leverage the AWS CLI tool to get the authentication token and check if we can get the profile. If we can’t successfully get the profile to do authentication, we use AWS CLI to fetch your CodeArtifact token.

That’s it. Happy coding.

#Android #AWS #Android/Gradle