初めに
こちらは
AWSで作成した環境をFormer2を使ってリバースでIaCしてみたので公開 #環境構築編
にてFormer2で出力したファイルを使ってCloudFormationで環境を作るときのトライアンドエラーをつらつら書いた記事になります。
なぜ掲題のことやりたいと思ったかというと、ツールの検証環境作ったのはよかったのですが
同系統の別ツール触ってみたいときにきれいな環境でやりたいなと思ったときに今までの環境流用したいなと思ったからです。
ちょっと設定変えた別環境とか、どの環境がどう違うのかがファイルベールでDiffとればわかるくらいならどの環境がどう違うかはわかりやすいかなと思ったりもしたからです。
IaCを1からやるのが面倒くさいだけ、とかでは決してないです!!
それではつらつら書いていきます。
出てたらまずそうな値とか利用用途知らない値は***でマスクしてます。
※任意に着けている名前はなるべく残しておきます(環境構築編で修正後のファイルなら公開しているので並べて見れるように)
エラー1:「Resource handler returned message: "Invalid parameter at 'lifecyclePolicyText' failed to satisfy constraint: 'Member must not be null' (Service: Ecr, Status Code: 400, Request ID: ***)" (RequestToken: ***, HandlerErrorCode: GeneralServiceException)」
これは、ライフサイクルが設定されていないかららしい?
下記を参考に追加する。
エラー2:Circular dependency between resources: [IAMRole2, CodeBuildProject, CodePipelinePipeline, IAMManagedPolicy4]
循環エラーということらしい
つまるところ参照しあっているとどれから作っていいかわからなくなるからエラーになるらしい
そのためエラー内容に書いてある設定を見て、今回はCodePipelinePipelineがわざわざ参照する必要のないところで参照していたので書き換えて修正
エラー3:「Resource handler returned message: "The role with name ***-codebuild-service-role cannot be found. (Service: Iam, Status Code: 404, Request ID: ***)" (RequestToken: ***, HandlerErrorCode: NotFound)」
ロールがないよと言われた、順番どうなっているとみてみると
Roles:
- !Sub "${CodeBuildProject}-service-role
となっていて多分!Subだとロールとの優先度が決められないのだろうということで!Refに変えて作成順番を自動で決定してもらえるように
Roles:
- !Ref IAMRole2
とする。
エラー4:「Resource handler returned message: "Invalid request provided: IamCertificateId or AcmCertificateArn can be specified only if SslSupportMethod must also be specified and vice-versa." (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
SslSupportMethodは知らないので検索したら
CloudFrontDistribution:
・・・
ViewerCertificate:
CloudFrontDefaultCertificate: true
MinimumProtocolVersion: "TLSv1"
SslSupportMethod: "vip"
となっていた。
SslSupportMethodはこれ単体で設定はできないらしいので
を参考に
CloudFrontDistribution:
・・・
ViewerCertificate:
CloudFrontDefaultCertificate: true
に修正したら解消
エラー5:「Resource handler returned message: "Invalid request provided: CreateService error: Unable to describe task definition. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: ***; Proxy: null)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
いろいろ試しながらやってしまったのでこのエラーに対しての修正であるかは怪しいが
ECSのtaskを作成する際にまだコンテナイメージが無いが指定必須になっている。
そのため暫定回避として、stack用のファイルを2つ作り初回用と、コンテナイメージ作成完了後のECS設定更新用を作成して回避した。(もっと別の方法がある気はする)
エラー6:「You have specified two resources that belong to different networks. (Service: AmazonEC2; Status Code: 400; Error Code: InvalidGroup.NotFound; Request ID: ***; Proxy: null)」
デフォルトのセキュリティグループに名前つけてなくて、Former2で出力されてなかったためAWSで設定されているセキュリティグループのIDがそのまま指定されていて、別のVPCのセキュリティグループ使おうとしていたので怒られてました。(というかこれ系のエラーがすごく多かった。。。これからはちゃんと名前つけよ。。。)
また、自己参照型のセキュリティグループを頭使わずに作成しようとすると循環エラーになるので下記を参考にデフォルトのセキュリティグループを作りました。
エラー7-1「Resource handler returned message: "VPC vpc-*** has no internet gateway (Service: ElasticLoadBalancingV2, Status Code: 400, Request ID: ***)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
VPCにインターネットゲートウェイが設定されていないからロードバランサー設定できませんと言われてる
コンソール上で確認してみると確かにない、でもインターネットゲートウェイ自体は設定できている。
つまるところはアタッチできていなかった。
Former2からはアタッチする設定は出力されないのだろうか、出力されるようにするやり方はあるのだろうか?
下記を追加
EC2InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref EC2InternetGateway
VpcId: !Ref EC2VPC
エラー7-2アタッチがロードバランサ作成より先に実行されない
下記を参考に対象のロードバランサ(ElasticLoadBalancingV2LoadBalancer)に
DependsOn: EC2InternetGatewayAttachment
を追加、明示的に順番を指定するのが必要な時もあるんですね。
エラー8「aws: prefixed tag key names are not allowed for external use.」
エラーの内容通りだが、tagなどに「aws:」から始まるものを入れているとエラーになる
確認したところ今回はECSでデプロイした時に自動で作成されていたType: "AWS::EC2::NetworkInterface"
が設定されているものをいれており、これはECSにデプロイするときにCodepipelineにて自動で作ってくれるため削除
エラー9「Resource handler returned message: "Invalid request provided: Create TaskDefinition: Task definition doesn't have any essential container. (Service: AmazonECS; Status Code: 400; Error Code: ClientException; Request ID: ***; Proxy: null)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
いろいろ試してたらTaskDefinitionでコンテナの設定が消えてたり
資材側の設定をミスしていてコンテナイメージを古い方というかコピー元のECRリポジトリにプッシュしていて
新しく作ったECRリポジトリにプッシュされておらずコンテナイメージが無かったので(資材側のPushするコンテナURL)
エラー10「Resource handler returned message: "Invalid request provided: CreateService error: You cannot specify an IAM role for services that require a service linked role. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: ***; Proxy: null)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
サービスで使用するロールは決まっているとのことでロール指定している部分を削除
エラー11「Resource handler returned message: "Invalid request provided: CreateService error: The target group with targetGroupArn arn:aws:elasticloadbalancing:ap-northeast-1::targetgroup/-targetgp-simpleapi/*** does not have an associated load balancer. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: ***; Proxy: null)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
これも作成順番のエラー
DependsOn: ElasticLoadBalancingV2Listener
をECSServiceに追加
エラー12「Resource handler returned message: "Only one primary private IP address can be specified. (Service: Ec2, Status Code: 400, Request ID: ***)" (RequestToken: ***, HandlerErrorCode: InvalidRequest)」
エラー8同様
ECSでデプロイした時に作成されていたものをいれてしまっていたため削除
エラー13ECSサービス作成が終わらない
ECSの状態を確認してみると「ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve ecr registry auth: service call has been retried 3 time(s): RequestError: send request failed caused by: Post "https://api.ecr.ap-northeast-1.amazonaws.com/": dial tcp ***: i/o timeout. Please check your task network configuration.」
とあり、内容としてはECRからのPullの失敗
下記を参考に諸々を追加して解消
エラー13「Resource handler returned message: "private-dns-enabled cannot be set because there is already a conflicting DNS domain for api.ecr.ap-northeast-1.amazonaws.com in the VPC vpc-*** (Service: Ec2, Status Code: 400, Request ID: ***)" (RequestToken: ***, HandlerErrorCode: GeneralServiceException)」
これはエラー13修正後にいろいろ作り直ししている際に発生
VPCエンドポイントは削除を行うとDNSが消えるまで時間がかかるかららしい
下記を参考に発生してから30分ほどおいて再度やったら出なかった。
エラー14「ResourceInitializationError: failed to validate logger args: create stream has been retried 1 times: failed to create Cloudwatch log group: AccessDeniedException: User: arn:aws:sts:::assumed-role/ecsTaskExecutionRole/ is not authorized to perform: logs:CreateLogGroup on resource: arn:aws:logs:ap-northeast-1::log-group:/ecs/-ecs-task:log-stream: because no identity-based policy allows the logs:CreateLogGroup action status code: 400, request id: *** : exit status 1」
ロググループ無くね?って言ってエラーになっている
awslogs-create-group: "true"
ぱっとみこれでなければ自動作成してくれそうだと思い込んでた。
下記を参考にロググループを作成
エラー15 ECSでdocker pullできない
やったこと1 プライベートECRなのでアクセス許可の設定を追加
RepositoryPolicyText : !Sub |
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPushPull",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${AWS::AccountId}:user/${IamUser}"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
}
]
}
やったこと2 ルートテーブルにて明示的なサブネットの関連付けされていなかったため関連付けを実施
Former2からアタッチするコードが出力されていなかった、やっぱりアタッチ系は出してくれないのかな?
EC2RouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref EC2RouteTable
SubnetId: !Ref EC2Subnet2
EC2RouteTableAssociation2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref EC2RouteTable3
SubnetId: !Ref EC2Subnet3
EC2RouteTableAssociation3:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref EC2RouteTable2
SubnetId: !Ref EC2Subnet
EC2RouteTableAssociation4:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref EC2RouteTable2
SubnetId: !Ref EC2Subnet4
やったこと3 ルートテーブルにインターネットゲートウェイが設定されていない
パブリックサブネット用のルートテーブルに
EC2Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref EC2RouteTable2
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref EC2InternetGateway
を追加
終わりに
ここに出していないシンタックスエラー系とか、合わせて出力されてないといけなかった設定が出力されてないエラー系が
とにかく多く、エラー自体はここに出してる4倍くらいは出てた気がする。
あと、サービスによっては作成までに時間が結構かかったり、ロールバックで止まってしまったりで待ち時間が長かった。
かかった時間的にはそうでもないのかもしれない、見たことないエラーばっかりだから気疲れしただけな気がする
一旦Former2で出力した同一のAWSアカウント上で動作する構築できることを目標で10時間くらいで
別AWSアカウント上で動作する構築できることを目標でもうプラス10時間くらい
公開できるように固定値だったりアカウントIDの環境変数化とかで、もうプラス5時間くらい
大体25時間くらいかかった気がする
根気がいる作業だったけど何とか(自分の環境では)動くようになってくれたのでよかった。。。