14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

mixiグループAdvent Calendar 2016

Day 14

S3でprivateなmavenリポジトリを管理する

Posted at

mixiグループ Advent Calendar 2016の14日目の記事です。

最近S3を使ったmavenリポジトリを導入してみたのでその時のメモを公開します。
Gradle2.4からS3をリポジトリとして使うためのサポートが入っているので比較的かんたんに設定できました。

ライブラリ側の設定

リポジトリに登録するために、ライブラリのリポジトリ設定、publish用のpluginの設定、アップロードされるS3の設定が必要になります。

ライブラリのリポジトリ設定

ここではpluginにmaven-publishを使っていますが、他のpluginでも設定はできるはずなので別のpluginを使う場合は読み替えてください

apply plugin: 'maven-publish'

publishing {
    repositories {
        maven {
            url "s3://someS3Bucket/maven2"
            credentials(AwsCredentials) {
                accessKey "someKey"
                secretKey "someSecret"
            }
        }
    }
    publications {
        maven(MavenPublication) {
            groupId = GROUP_ID
            artifactId = ARTIFACT_ID
            version = VERSION
            // ライブラリの依存をpomに反映
            pom.withXml {
                def dependenciesNode = asNode().appendNode('dependencies')
                configurations.compile.allDependencies.each { dependency ->
                    def dependencyNode = dependenciesNode.appendNode('dependency')
                    dependencyNode.appendNode('groupId', dependency.group)
                    dependencyNode.appendNode('artifactId', dependency.name)
                    dependencyNode.appendNode('version', dependency.version)
                }
            }

            // aarは直接指定
            artifact source: file("${project.buildDir}/outputs/aar/example-release.aar")
            // javadoc付きjarや、source付きjarを指定する必要があればartifactとして追記
        }
    }
}

AWSの設定

AWSにもいくつかの設定が必要になります

バケットの作成

当然ながらS3のバケットがなければファイルを置くことができないので作成します。
この時に静的ウェブサイトホスティングを有効にしておきます。
すでに存在しているバケットを利用する場合は必要ありません

バケットにアクセスするためのIAMポリシーを作成する

ライブラリユーザー用の読み込み専用のポリシーとアップロード可能なポリシーの2つを作成します。

ライブラリユーザー用ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::someS3Bucket/*",
                "arn:aws:s3:::someS3Bucket"
            ]
        }
    ]
}

アップロード可能ユーザー用ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::someS3Bucket/*",
                "arn:aws:s3:::someS3Bucket"
            ]
        }
    ]
}

IAMユーザーを作成

ライブラリを利用するユーザーとライブラリを作成するユーザーの2つのユーザーを作成します
access_keyとsecretはこの後使うので必ず控えておきます。
先程作成したポリシーをそれぞれにアタッチします

IAMのユーザーからアクセス権限-アクセス権限の追加で設定したIAMポリシーをアタッチする
このタイミングでAWS CLIなどを利用してバケットへのアクセスが正常にできること(権限がない場合はアクセスができないことも)を確認しておくことをおすすめします

ライブラリを使う側の設定

ライブラリを使う側は下記の設定のみで、aarを参照することが可能になります

repositories {
    maven {
        url "s3://someS3Bucket/maven2"
        credentials(AwsCredentials) {
            accessKey "someKey" // read-only-key
            secretKey "someSecret"
        }
    }
}
dependencies {
    compile "com.example:lib:1.0.0"
}

ライブラリを使う側のsourceリポジトリにaccess keyを埋め込むことでユーザー管理をしなくてもライブラリを使う権限を持っている人はライブラリを参照できることになります。

事故防止のためのtips

ライブラリ側のリポジトリの設定を

repositories {
    maven {
        url "s3://someS3Bucket/maven2"
        credentials(AwsCredentials) {
            accessKey "someKey"
            secretKey "someSecret"
        }
    }
}

とすると上で書いていますが、開発者が誤って手元のバイナリをpublishしないためにurlやaccessKey,secretKeyは直接埋め込まないで、gradle.propertiesにread-onlyなキーを記述し、その上でリリース作業はCIサーバー上からのみ行うようにすることをおすすめします。
なので、記述としては以下のようになると思います
gradle.properties

YOUR_REPOSITORY_URL=s3://someS3Bucket/maven2
REPOSITORY_ACCESS_KEY=someKey
REPOSITORY_SECRET_KEY=someSecret
repositories {
    maven {
        url YOUR_REPOSITORY_URL
        credentials(AwsCredentials) {
            accessKey REPOSITORY_ACCESS_KEY
            secretKey REPOSITORY_SECRET_KEY
        }
    }
}

read-onlyなキーにすることで、手元から誤ってリリースしてしまうことがなくなります。
CIサービスからのリリースを想定しているので、上記設定をした上でCIサーバに環境変数として

ORG_GRADLE_PROJECT_REPOSITORY_ACCESS_KEY=someKey
ORG_GRADLE_PROJECT_REPOSITORY_SECRET_KEY=someSecret

を設定すると、環境変数で設定した値が優先的に選択されるので、リポジトリへのリリースをすることができます。
gradleの変数の優先順位はgradleの公式ドキュメントの14章20章を読むといいと思います

おわりに

まだ運用を始めたばかりですが、今のところは特に問題もなく運用できています。
アクセスコントロールをAWSに任せられるのは楽でいいですね。

14
8
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
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?