勉強日記

チラ裏

CI/CDおぼえがき -- AWS CodeDeploy


CodeDeploy

  • AWS S3の特定のバケットの特定の位置にプロジェクトをtarballに固めて置いておく
    • tarとかtgzとか
  • Deploymentを作成すると、プロジェクトを取りに行って、ターゲットグループにデプロイしてくれる
  • デプロイの仕様はappspec.ymlに記述してプロジェクトルートに同梱して固める

ハマったとこ

CodeDeploy Agent

  • ちゃんとインストールする
    • 公式ドキュメントを読もうな
  • 疎通のためにHTTP 80, HTTPS 443を開けとく
  • IAMロール付与
    • CodeDeploy用AWS管理ポリシーがあるので活用する
      • CloudWatch, EC2, ELB, Resource Group Tagging, SNS等の許可が付与される
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "autoscaling:CompleteLifecycleAction",
                "autoscaling:DeleteLifecycleHook",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeLifecycleHooks",
                "autoscaling:PutLifecycleHook",
                "autoscaling:RecordLifecycleActionHeartbeat",
                "autoscaling:CreateAutoScalingGroup",
                "autoscaling:UpdateAutoScalingGroup",
                "autoscaling:EnableMetricsCollection",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribePolicies",
                "autoscaling:DescribeScheduledActions",
                "autoscaling:DescribeNotificationConfigurations",
                "autoscaling:DescribeLifecycleHooks",
                "autoscaling:SuspendProcesses",
                "autoscaling:ResumeProcesses",
                "autoscaling:AttachLoadBalancers",
                "autoscaling:PutScalingPolicy",
                "autoscaling:PutScheduledUpdateGroupAction",
                "autoscaling:PutNotificationConfiguration",
                "autoscaling:PutLifecycleHook",
                "autoscaling:DescribeScalingActivities",
                "autoscaling:DeleteAutoScalingGroup",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus",
                "ec2:TerminateInstances",
                "tag:GetResources",
                "sns:Publish",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:PutMetricAlarm",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeInstanceHealth",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "*"
        }
    ]
}

EC2へのS3アクセス権限付与

  • ターゲットグループのEC2に、S3読み取りアクセスを許可する
    • CodeDeployはEC2上のcodedeploy-agentに「S3にtarballを取りに行け」と指示するだけ
    • 実際にS3にアクセスするのはEC2
    • なので、EC2にS3へアクセス可能なIAMロールを付与する
  • インスタンス起動後にIAMロールを付与した場合、codedeploy-agentを再起動する必要あり
sudo systemctl restart codedeploy-agent
  • 忘れると、/var/log/aws/codedeploy-agent/に「認証情報がないぞ」という旨のエラーログが吐き出される
    • IAM Roleにより自動的に払い出されるはずのAccess Key類がないということ
2019-12-21 17:58:16 ERROR [codedeploy-agent(14200)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: 
Missing credentials - please check if this instance was started with an IAM instance profile

プロジェクトのtarballの固め方

これは駄目

tar -czvf project.tgz project

tarballが深くなって、「appspec.ymlがルートにないぞ」ってなる

2019-12-21 18:32:01 ERROR [codedeploy-agent(15059)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Error during perform: RuntimeError - 
The CodeDeploy agent did not find an AppSpec file within the unpacked revision directory at revision-relative path "appspec.yml". The revision was unpacked to directory

これも駄目

cd project
tar -czvf project.tgz .

アーカイブ中に作業ディレクトリ上にtgzが追加され、下記警告が出る

/bin/tar: .: file changed as we read it

exitコードがnon-zeroなのでCI/CDはfailとなる

正しくはこう

tar -C peoject -cvzf project.tgz  .