5
5

More than 3 years have passed since last update.

AWS CodeArtifactをMavenから使ってみる

Last updated at Posted at 2020-07-26

What's?

  • 2020年6月に登場した、AWS CodeArtifactを使ってみたい
  • そもそも、AWS CodeArtifactとはどういうものか?
  • 試しに使ってみる

ということを調べたり、やってみたりする記事です。

最後の「使ってみる」の部分には、Apache Mavenを利用します。つまり、Javaでのサンプルということになりますね。

AWS CodeArtifactとは

AWSの提供する、マネージドなアーティファクトリポジトリサービスです。

AWS CodeArtifact

AWS CodeArtifact Documentation

AWS CodeArtifact によるソフトウェアパッケージ管理

AWSがソフトウェアパッケージのリポジトリサービス「AWS CodeArtifact」正式リリース。npmやMavenなどのパッケージを共有可能

平たく言うと、ソースコードをビルドしたりして生成された、パッケージを管理してくれるものになります。

対応しているのは、このあたりですね。

  • npm
  • PyPI
  • Maven

AWS CodeArtifact Concepts / Package

要するに、JavaScript、Python、Java、の3つですと。

AWS CodeArtifactを使わない場合は、以下のような選択肢から環境を構築していることかと思います(GitHub Packagesは違いますが)。

この管理を、AWSに任せることができるというサービスですね。

AWS CodeArtifactにおける要素

「AWSが提供するマネージドなパッケージリポジトリだ」と書くとあっさりしていますが、いろいろと概念、要素があるようなので理解しておく必要がありそうですね。

順にちょっと見ていってみましょう。

概要自体は、こちらに書いてあります。

AWS CodeArtifact Concepts

リポジトリ

パッケージをまとめたもので、おそらく他のパッケージマネージャーを知っていると、1番理解のしやすい概念かと。

AWS CodeArtifact Concepts / Repository

リポジトリは、各種パッケージマネージャーのクライアントツール(npm、PyPI、Mavenなど)のエンドポイントとなります。

アクセス制御を行うためのポリシーを設定することもできます。

また、リポジトリはPolyglotであり、複数の言語で利用することができます。言語ごとにリポジトリを作らなくても良い、と言っていますね。

リポジトリは、後述のドメイン内に作ることになります。ドメインなしのリポジトリは存在できません。

You cannot create a repository without a domain. When you use the CreateRepository API to create a repository, you must specify a domain name. You cannot move a repository from one domain to another.

Domain overview

また、アップストリームのリポジトリも持つことができたり、外部リポジトリへの接続を行うことができます。

Add an external connection

外部接続を追加すると、AWS CodeArtifactリポジトリにパッケージがない場合に、パブリックなnpm RegistryやMaven Repositoryなどの外部リポジトリからパッケージを取得することができます。

パッケージ / パッケージバージョン / アセット

パッケージは、パッケージマネージャーを使ってソフトウェアをインストールするために必要となるメタデータです。

AWS CodeArtifact Concepts / Package

また、パッケージを構成するアセット(.tgzファイルやJARファイルなど)を含めたものが、パッケージバージョンです。

AWS CodeArtifact Concepts / Package version

AWS CodeArtifact Concepts / Asset

ドメイン

リポジトリを集約する概念のようです。

AWS CodeArtifact Concepts / Domain

パッケージのアセットとメタデータの保存先は、実はリポジトリではなくドメインです。ドメイン内にいくつリポジトリがあっても、ドメイン内に同じバージョン、アセットのパッケージは1回だけ保存されます。

また、AWS KMSを使った暗号化も行われます。

パッケージの取得は、リポジトリを介して行うことになります。

ドメインはアカウント内で複数持つことができますが、通常は単一のドメインを勧めているようです。

Although an organization can have multiple domains, we recommend a single production domain that contains all published artifacts so that teams can find and share packages across their organization.

ドメインの内容を見ると

  • リポジトリのストレージ+暗号化
  • リポジトリ間のメタデータのコピー(※アップストリームリポジトリに関連)
  • アクセス管理(リポジトリにアクセスすることができるアカウント制限や、ポリシーの管理)
  • リポジトリの名前空間の提供

といったところがドメインの主な機能なようですね。

Domain overview

アップストリームリポジトリ

AWS CodeArtifact Concepts / Upstream repository

アップストリームリポジトリに関しては、個別のドキュメントを見た方がわかりやすい気がします。

Working with upstream repositories in CodeArtifact

AWS CodeArtifactリポジトリが、他のAWS CodeArtifactリポジトリをアップストリーム(上流)のリポジトリにすることができる、というものです。

こういう使い方も可能みたいですね。

If an upstream repository has an external connection to a public repository, the repositories that are downstream from it can pull packages from that public repository. For example, suppose that the repository my-repo has an upstream repository named upstream, and upstream has an external connection to a public npm repository. In this case, a package manager that is connected to my-repo can pull packages from the npm public repository.

アップストリームリポジトリに対してパブリックな外部リポジトリへの接続を定義し、ダウンストリームリポジトリからアップストリームリポジトリ経由でパブリックリポジトリからパッケージを取得する、といったケースですね。

始め方(ざっくり)

AWS CodeArtifactの使う時のざっくりした流れを書きます。

まあ、ここのまとめなんですけど。

Getting started using the AWS CLI

AWS CodeArtifact側

  1. ドメインを作成する
  2. リポジトリを作成する

外部リポジトリへの接続定義は、任意でしょう。

パッケージマネージャーのクライアント側

  1. AWS CodeArtifactへログインする
  2. パッケージマネージャーのクライアントの設定に、リポジトリの情報を追加する
  3. 使う

最初にログインがあるのがポイントで、トークンを発行して環境変数に設定する、などの手順を踏む必要があります。

Authentication with npm

Configure pip without the login command

Using Maven / Pass an auth token using an environment variable

使ってみる

と、前置きはこれくらいにして、そろそろ使っていってみましょう。

AWS CodeArtifactでリポジトリを作って、Java(Maven)で使ってみる、というのを今回のシナリオにしてみます。

今回の環境は、こちらです。

$ aws --version
aws-cli/2.0.34 Python/3.7.3 Linux/4.15.0-112-generic botocore/2.0.0dev38

AWSのクレデンシャルは、環境変数で設定しているものとします。

$ export AWS_ACCESS_KEY_ID=.....
$ export AWS_SECRET_ACCESS_KEY=.....
$ export AWS_DEFAULT_REGION=.....

AWS CodeArtifactのリポジトリを作る

こちらを参考に。

Getting started using the AWS CLI

なお、普段ならこの手のものはTerraformで構築するのですが、TerraformがまだAWS CodeArtifactには対応していないので、AWS CLIでやっていきます。

(余談)Terraformでのサポートに関するissue
Add AWS CodeArtifact service support

AWS CLIでの、AWS CodeArtifactに関するリファレンスはこちら。

codeartifact

最初に、AWS KMS CMKを作成します。

$ aws kms create-key
$ aws kms create-alias --alias-name alias/code-artifact-key --target-key-id [作成したAWS KMS(CMK)のARN]

今回は、専用のキーにしました。キーを指定しない場合は、AWSが管理するキーが使われるようです。

そして、このCMKを使ってドメインを作ります。ドメイン名は、ドキュメントのそのままですが、my-domainにしました。

$ aws codeartifact create-domain --domain my-domain --encryption-key alias/code-artifact-key

次に、リポジトリを作成します。リポジトリを作成するには、ドメイン名を指定する必要があります。

$ aws codeartifact create-repository --domain my-domain --repository my-repo

リポジトリ名も、ドキュメントそのままmy-repoにしました。

ドキュメントにある-domain-ownerというオプションは完全に無視しましたが、今回はそのまま作成したAWSアカウントIDが使われます。

ドキュメントでは、他にも外部リポジトリへの接続やアップストリームなどの例がありますが、今回はここまでで。

作成したドメイン、リポジトリの情報を確認してみましょう。

$ aws codeartifact describe-domain --domain my-domain
{
    "domain": {
        "name": "my-domain",
        "owner": "[AWSアカウントID]",
        "arn": "arn:aws:codeartifact:ap-northeast-1:[AWSアカウントID]:domain/my-domain",
        "status": "Active",
        "createdTime": "2020-07-26T14:32:35.003000+09:00",
        "encryptionKey": "arn:aws:kms:ap-northeast-1:[AWSアカウントID]:key/a6529646-1a8a-4772-a28a-b62c1e82992c",
        "repositoryCount": 1,
        "assetSizeBytes": 0
    }
}


$ aws codeartifact describe-repository --domain my-domain --repository my-repo
{
    "repository": {
        "name": "my-repo",
        "administratorAccount": "[AWSアカウントID]",
        "domainName": "my-domain",
        "domainOwner": "[AWSアカウントID]",
        "arn": "arn:aws:codeartifact:ap-northeast-1:[AWSアカウントID]:repository/my-domain/my-repo",
        "upstreams": [],
        "externalConnections": []
    }
}

これで、準備は完了です。

Mavenから使う

では、Mavenから使ってみましょう。

ドキュメントは、こちらを参考に。

Using CodeArtifact with Maven

今回の環境は、こちらです。

$ java --version
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu118.04.1, mixed mode, sharing)


$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 11.0.8, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-112-generic", arch: "amd64", family: "unix"

こちらを見ながら、やっていってきましょう。

Use CodeArtifact with mvn

settings.xmlの作成と、認証トークンの取得

まずはsettings.xmlを用意します。今回は、このサンプル専用に作成することにしました。

settings.xml

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
        <server>
            <id>codeartifact</id>
            <username>aws</username>
            <password>${env.CODEARTIFACT_TOKEN}</password>
        </server>
    </servers>
</settings>

ユーザー名はawsみたいですね。パスワードは、環境変数として設定します。

こんな感じですね。

$ export CODEARTIFACT_TOKEN=`aws codeartifact get-authorization-token --domain my-domain --query authorizationToken --output text`

Pass an auth token using an environment variable

注意事項にもありますが、この認証トークンの有効期限は最大で12時間だそうです。これが切れると、都度取得する必要があります。

CodeArtifact authorization tokens are valid for a default period of 12 hours. You can change how long a token is valid using the --durationSeconds argument (max authorization period is 12 hours). When the authorization period expires, you must call get-authorization-token to get another token. The authorization period begins after get-authorization-token is called.

毎日取得してね、という感じですね。

アーティファクトをリポジトリにアップロードする

続いて、アーティファクトをリポジトリにアップロードしてみます。というわけで、簡単なライブラリを作ってみましょう。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github.charon.r13b</groupId>
    <artifactId>library</artifactId>
    <version>0.0.1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>codeartifact</id>
            <name>codeartifact</name>
            <url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/</url>
        </repository>
    </repositories>

    <distributionManagement>
        <repository>
            <id>codeartifact</id>
            <name>codeartifact</name>
            <url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo</url>
        </repository>
    </distributionManagement>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>
    </dependencies>
</project>

今回の例ではrepositories/repositoryは不要なのですが、なんとなく。少なくとも、distributionManagementの方のrepositoryがあればOKです。

Apache Commons Langは、なんとなく依存する外部ライブラリとして使っておきました。

ドキュメントを見た時の以下のURLの解釈に迷ったのですが、

<url>https://my-domain-domain-owner-id.d.codeartifact.us-west-2.amazonaws.com/maven/my-repo/</url>

こう読めばいいんですね。

<url>https://[AWS CodeArtifactのドメイン名]-[ドメインのOwner id(AWSアカウントID)].d.codeartifact.[リージョン].amazonaws.com/maven/[リポジトリ名]/</url>

あとは、mvn deployで。今回は、settings.xmlはオプションで指定しています。

$ mvn deploy -s settings.xml

BUILD SUCCESSになれば、アーティファクトがアップロードされているので、確認してみましょう。

$ aws codeartifact list-packages --domain my-domain --repository my-repo
{
    "packages": [
        {
            "format": "maven",
            "namespace": "com.github.charon.r13b",
            "package": "library"
        }
    ]
}

OKです。

アップロードされたアーティファクトを使ってみる

最後に、アップロードされたアーティファクトを使ってみます。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github.charon.r13b</groupId>
    <artifactId>app</artifactId>
    <version>0.0.1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>codeartifact</id>
            <name>codeartifact</name>
            <url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.github.charon.r13b</groupId>
            <artifactId>library</artifactId>
            <version>0.0.1</version>
        </dependency>
    </dependencies>
</project>

こちらは利用側なので、repositories/repositoryの定義があればOKです。

    <repositories>
        <repository>
            <id>codeartifact</id>
            <name>codeartifact</name>
            <url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/</url>
        </repository>
    </repositories>

depencencies/dependencyには、先ほどアップロードしたアーティファクトを含めています。

    <dependencies>
        <dependency>
            <groupId>com.github.charon.r13b</groupId>
            <artifactId>library</artifactId>
            <version>0.0.1</version>
        </dependency>
    </dependencies>

サンプルコードは、こんな感じで。

src/main/java/com/github/charon/r13b/app/App.java

package com.github.charon.r13b.app;

import com.github.charon.r13b.library.MessageService;

public class App {
    public static void main(String... args) {
        MessageService messageService = new MessageService("★★★", "★★★");
        System.out.println(messageService.decorate("Hello World!!"));
    }
}

ビルドして、実行。settings.xmlは、アーティファクトをアップロードした時に使ったものと、同じものを使用しています。

$ mvn compile exec:java -s settings.xml -Dexec.mainClass=com.github.charon.r13b.app.App

実行できました、と。

[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ app ---
★★★Hello World!!★★★

なお、認証トークンがない状態だと、401になるのでアーティファクトを使うのにも認証が必要ですよ、と。

[ERROR] Failed to execute goal on project app: Could not resolve dependencies for project com.github.charon.r13b:app:jar:0.0.1: Failed to collect dependencies at com.github.charon.r13b:library:jar:0.0.1: Failed to read artifact descriptor for com.github.charon.r13b:library:jar:0.0.1: Could not transfer artifact com.github.charon.r13b:library:pom:0.0.1 from/to codeartifact (https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/): Authentication failed for https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/com/github/charon/r13b/library/0.0.1/library-0.0.1.pom 401 Unauthorized

## ココ
401 Unauthorized 

これで、確認ができました。

ポリシーについて

今回、利用したIAMユーザーがAdministratorAccessポリシーを持っていたのでなんでもやれているのですが、実際にはIAMユーザーでアーティファクトのアップロードの可否、参照の可否などを設定していくことになると思います。

ドメイン、リポジトリにそれぞれ設定できるので、見ておきましょう。

Domain policies

Repository policies

後片付け

最後に作成したリソースの後片付けをしておきます。

リポジトリとドメインの削除。

$ aws codeartifact delete-repository --domain my-domain --repository my-repo
$ aws codeartifact delete-domain --domain my-domain

AWS KMSのCMKの削除。

$ aws kms delete-alias --alias-name alias/code-artifact-key
$ aws kms schedule-key-deletion --key-id [AWS KMS(CMK)のキーID]
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5