From 8d30554c4a17f28c2492f93c6b15433cd3cc97e1 Mon Sep 17 00:00:00 2001 From: jooyoung Date: Sat, 9 Mar 2024 21:38:45 -0800 Subject: [PATCH] fix execution error issue --- .../ecsdemo-cicd/buildspec-cicd.yml | 30 +++++++ application-code/ecsdemo-cicd/buildspec.yml | 8 +- terraform/.gitignore | 79 +++++++++++++++++++ terraform/cicd-examples/README.md | 20 ++--- .../external-state-bucket/main.tf | 5 -- .../lb-service-container-pipeline/main.tf | 54 ++++++++----- .../lb-service-container-pipeline/variable.tf | 2 +- .../lb-service-external-state/main.tf | 8 +- terraform/modules/codebuild-iac/main.tf | 68 +++++++--------- 9 files changed, 194 insertions(+), 80 deletions(-) create mode 100644 application-code/ecsdemo-cicd/buildspec-cicd.yml create mode 100644 terraform/.gitignore diff --git a/application-code/ecsdemo-cicd/buildspec-cicd.yml b/application-code/ecsdemo-cicd/buildspec-cicd.yml new file mode 100644 index 00000000..307a02c9 --- /dev/null +++ b/application-code/ecsdemo-cicd/buildspec-cicd.yml @@ -0,0 +1,30 @@ +version: 0.2 + +phases: + pre_build: + commands: + - echo $REPO_URL + - REPOSITORY=${REPO_URL%/*} + - echo Logging in to Amazon ECR... + - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $REPOSITORY + - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) + - IMAGE_TAG=${COMMIT_HASH:=latest} + build: + commands: + - echo Build started on `date` + - echo Building the Docker image... + - docker build -t $REPO_URL . + post_build: + commands: + - echo Building Task Definition + - python3 create-configs.py $REPO_URL:$IMAGE_TAG core-infra-external-state ecsdemo-frontend development us-west-2 + - echo Pushing the Docker image... + - docker tag $REPO_URL $REPO_URL:$IMAGE_TAG + - docker push $REPO_URL:$IMAGE_TAG + - echo Preparing spec files in new folder + - mkdir artifacts + - printf '[{"name":"%s","imageUri":"%s"}]' "$CONTAINER_NAME" "$REPO_URL:$IMAGE_TAG" > artifacts/imagedefinitions.json + - cat artifacts/imagedefinitions.json +artifacts: + files: + - '**/*' \ No newline at end of file diff --git a/application-code/ecsdemo-cicd/buildspec.yml b/application-code/ecsdemo-cicd/buildspec.yml index 88367f69..802c3360 100644 --- a/application-code/ecsdemo-cicd/buildspec.yml +++ b/application-code/ecsdemo-cicd/buildspec.yml @@ -13,11 +13,10 @@ phases: commands: - echo Build started on `date` - echo Building the Docker image... - - docker build -t $REPO_URL . + - docker build -t $REPO_URL $FOLDER_PATH post_build: commands: - - echo Building Task Definition - - python3 create-configs.py $REPO_URL:$IMAGE_TAG core-infra ecsdemo-frontend development us-west-2 + - echo Build completed on `date` - echo Pushing the Docker image... - docker tag $REPO_URL $REPO_URL:$IMAGE_TAG - docker push $REPO_URL:$IMAGE_TAG @@ -25,6 +24,9 @@ phases: - mkdir artifacts - printf '[{"name":"%s","imageUri":"%s"}]' "$CONTAINER_NAME" "$REPO_URL:$IMAGE_TAG" > artifacts/imagedefinitions.json - cat artifacts/imagedefinitions.json + artifacts: files: - '**/*' + base-directory: 'artifacts' + discard-paths: yes \ No newline at end of file diff --git a/terraform/.gitignore b/terraform/.gitignore new file mode 100644 index 00000000..ff57159d --- /dev/null +++ b/terraform/.gitignore @@ -0,0 +1,79 @@ +build/ +plan.out +plan.out.json + +# Local .terraform directories +.terraform/ + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Exclude all .tfvars files, which are likely to contain sentitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +# +#*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc +.terraform.lock.hcl + +go.mod +go.sum + +# Build files +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.envrc + +# CDK directories +cdk.out/ +cdk.context.json + +# Python +__pycache__/ + +# Customized ENV files +.env* +.venv/ +output.json diff --git a/terraform/cicd-examples/README.md b/terraform/cicd-examples/README.md index c78b0ade..174e7ea4 100644 --- a/terraform/cicd-examples/README.md +++ b/terraform/cicd-examples/README.md @@ -18,6 +18,7 @@ Before deploying this example, ensure you have the following: - An AWS account with the necessary permissions. - AWS CLI configured with the appropriate credentials. +- JQ installed (https://jqlang.github.io/jq/download/) ## Deployment Steps @@ -43,7 +44,7 @@ Before deploying this example, ensure you have the following: 3. Set local environment variable to reference deployed state bucket. ``` - STATE_BUCKET=$(aws ssm get-parameters --names terraform_state_bucket | jq -r '.Parameters[0].Value') + STATE_BUCKET=$(aws ssm get-parameters --names terraform_state_bucket --region us-west-2 | jq -r '.Parameters[0].Value') ``` 4. Deploy the CodePipeline which will deploy the required infrastructure. @@ -57,36 +58,37 @@ Before deploying this example, ensure you have the following: ``` #Get IAC code commit repo - aws codecommit get-repository --repository-name iac_sample_repo --query 'repositoryMetadata.cloneUrlHttp' + YOUR_CODE_COMMIT_IAC_REPO=$(aws codecommit get-repository --repository-name iac_sample_repo --query 'repositoryMetadata.cloneUrlHttp' --region us-west-2 | jq -r .) #CD to terraform folder cd ../../../terraform git init - git remote add origin YOUR_CODE_COMMIT_IAC_REPO + git remote add origin $YOUR_CODE_COMMIT_IAC_REPO + git add . git commit -m "initial commit" git push origin main - ``` 6. Deploy the CodePipeline which will build and deploy new containers. ```bash - cd ../lb-service-container-pipeline + cd cicd-examples/lb-service-container-pipeline terraform init - terraform apply -var="s3_bucket=$STATE_BUCKET" + terraform apply ``` 7. Once the Pipeline has fully deployed the environment we can begin to CI/CD new containers. ``` # CD to sample app director - cd ../application-code/ecsdemo-cicd/ + cd ../../../application-code/ecsdemo-cicd/ #Get Application code commit repo - aws codecommit get-repository --repository-name iac_sample_repo --query 'repositoryMetadata.cloneUrlHttp' + YOUR_CODE_COMMIT_APP_REPO=$(aws codecommit get-repository --repository-name ecs_service_repo --query 'repositoryMetadata.cloneUrlHttp' --region us-west-2 | jq -r .) git init - git remote add origin YOUR_CODE_COMMIT_APP_REPO + git add . + git remote add origin $YOUR_CODE_COMMIT_APP_REPO git commit -m "initial application deployment" git push origin main ``` diff --git a/terraform/cicd-examples/external-state-bucket/main.tf b/terraform/cicd-examples/external-state-bucket/main.tf index 73338bb8..2cb3ebc6 100644 --- a/terraform/cicd-examples/external-state-bucket/main.tf +++ b/terraform/cicd-examples/external-state-bucket/main.tf @@ -8,11 +8,6 @@ resource "aws_s3_bucket" "terraform_state_bucket" { } } -resource "aws_s3_bucket_acl" "terraform_state_bucket" { - bucket = aws_s3_bucket.terraform_state_bucket.id - acl = "private" -} - resource "aws_s3_bucket_versioning" "terraform_state_bucket" { bucket = aws_s3_bucket.terraform_state_bucket.id versioning_configuration { diff --git a/terraform/cicd-examples/lb-service-container-pipeline/main.tf b/terraform/cicd-examples/lb-service-container-pipeline/main.tf index ad851b9a..6d6de4b9 100644 --- a/terraform/cicd-examples/lb-service-container-pipeline/main.tf +++ b/terraform/cicd-examples/lb-service-container-pipeline/main.tf @@ -2,23 +2,19 @@ provider "aws" { region = var.region } -data "aws_s3_bucket" "example" { - bucket = var.s3_bucket -} - ################################################################################ # Parameter Store ################################################################################ -# CodeDeploy Application Parameter -data "aws_ssm_parameter" "codedeploy_app" { - name = "/codedeploy/app/deploy_development_ecsdemo-frontend" -} +# # CodeDeploy Application Parameter +# data "aws_ssm_parameter" "codedeploy_app" { +# name = "/codedeploy/app/deploy_development_ecsdemo-frontend" +# } -# CodeDeploy Deployment Group Parameter -data "aws_ssm_parameter" "deployment_group" { - name = "/codedeploy/deployment-group/deploy_development_ecsdemo-frontend" -} +# # CodeDeploy Deployment Group Parameter +# data "aws_ssm_parameter" "deployment_group" { +# name = "/codedeploy/deployment-group/deploy_development_ecsdemo-frontend" +# } ################################################################################ # ECR and Git Repositories @@ -178,13 +174,35 @@ resource "random_id" "this" { byte_length = 8 } +module "codepipeline_s3_bucket" { + source = "terraform-aws-modules/s3-bucket/aws" + version = "~> 3.15" + + bucket_prefix = "codepipeline-${var.region}-" + # acl = "private" + + # For example only - please re-evaluate for your environment + force_destroy = true + + attach_deny_insecure_transport_policy = true + attach_require_latest_tls_policy = true + + server_side_encryption_configuration = { + rule = { + apply_server_side_encryption_by_default = { + sse_algorithm = "AES256" + } + } + } +} + module "build_container" { source = "../../modules/codebuild" name = "dev-lb-service-codebuild" service_role = aws_iam_role.codebuild_role.arn - buildspec_path = "../../../application-code/ecsdemo-cicd/buildspec.yml" - s3_bucket = data.aws_s3_bucket.example.id + buildspec_path = "./buildspec-cicd.yml" + s3_bucket = module.codepipeline_s3_bucket environment = { image = "aws/codebuild/standard:5.0" @@ -198,7 +216,7 @@ module "build_container" { } create_iam_role = true - iam_role_name = "dev-lb-service-build-codebuild-${random_id.this.hex}" + iam_role_name = "dev-codebuild-${random_id.this.hex}" ecr_repository = aws_ecr_repository.example_repo.arn } @@ -211,7 +229,7 @@ resource "aws_codepipeline" "example_applicaiton_pipeline" { role_arn = aws_iam_role.codepipeline_role.arn artifact_store { - location = data.aws_s3_bucket.example.bucket + location = module.codepipeline_s3_bucket.s3_bucket_id type = "S3" } @@ -263,8 +281,8 @@ resource "aws_codepipeline" "example_applicaiton_pipeline" { input_artifacts = ["BuildArtifact"] configuration = { - ApplicationName = data.aws_ssm_parameter.codedeploy_app.value - DeploymentGroupName = data.aws_ssm_parameter.deployment_group.value + ApplicationName = "deploy_development_ecsdemo-frontend" + DeploymentGroupName = "deployment-group-deploy_development_ecsdemo-frontend" TaskDefinitionTemplateArtifact = "BuildArtifact" TaskDefinitionTemplatePath = "development-task-definition.json" AppSpecTemplateArtifact = "BuildArtifact" diff --git a/terraform/cicd-examples/lb-service-container-pipeline/variable.tf b/terraform/cicd-examples/lb-service-container-pipeline/variable.tf index 4b7ec9e9..34c23c96 100644 --- a/terraform/cicd-examples/lb-service-container-pipeline/variable.tf +++ b/terraform/cicd-examples/lb-service-container-pipeline/variable.tf @@ -6,6 +6,6 @@ variable "region" { variable "s3_bucket" { type = string - default = "terraform-20240118200828358000000001" + default = "terraform-20240310021637223800000001" description = "s3 bucket" } diff --git a/terraform/cicd-examples/lb-service-external-state/main.tf b/terraform/cicd-examples/lb-service-external-state/main.tf index 8afacfb7..4891fdee 100644 --- a/terraform/cicd-examples/lb-service-external-state/main.tf +++ b/terraform/cicd-examples/lb-service-external-state/main.tf @@ -248,7 +248,7 @@ resource "aws_iam_role_policy_attachment" "codedeploy_policy_attachment" { data "aws_vpc" "vpc" { filter { name = "tag:Name" - values = ["core-infra"] + values = ["core-infra-external-state"] } filter { @@ -261,7 +261,7 @@ data "aws_vpc" "vpc" { data "aws_subnets" "public" { filter { name = "tag:Name" - values = ["core-infra-public-*"] + values = ["core-infra-external-state-public-*"] } filter { name = "tag:Environment" @@ -272,7 +272,7 @@ data "aws_subnets" "public" { data "aws_subnets" "private" { filter { name = "tag:Name" - values = ["core-infra-private-*"] + values = ["core-infra-external-state-private-*"] } tags = { Environment = var.environment @@ -292,7 +292,7 @@ data "aws_ecs_cluster" "core_infra" { tags = { Environment = var.environment } - cluster_name = "core-infra" + cluster_name = "core-infra-external-state" } diff --git a/terraform/modules/codebuild-iac/main.tf b/terraform/modules/codebuild-iac/main.tf index ac582449..2a4d49bc 100644 --- a/terraform/modules/codebuild-iac/main.tf +++ b/terraform/modules/codebuild-iac/main.tf @@ -27,61 +27,48 @@ resource "aws_iam_policy" "codebuild_all_permissions" { { Effect = "Allow", Action = [ - "ssm:GetParameter", - "ssm:GetParameters", - "ssm:PutParameter", - "ssm:DescribeParameters", - "ssm:ListTagsForResource", - "ssm:DeleteParameter", - "logs:*", + "cloudwatch:PutMetricData", + "codebuild:*", + "codedeploy:*", + "codepipeline:*", "ec2:*", "ecs:*", - "iam:PassRole", - "servicediscovery:*", - "s3:ListBucket", - "s3:GetObject", - "s3:PutObject", - "codepipeline:*", - "codebuild:*", - "cloudwatch:PutMetricData", "elasticloadbalancing:*", - "codedeploy:*", - "iam:GetPolicy", - "iam:CreateRole", "iam:AttachRolePolicy", - "iam:GetPolicyVersion", - "iam:GetRole", - "iam:GetRolePolicy", - "iam:ListAttachedRolePolicies", - "iam:ListRolePolicies", - "iam:ListRoles", - "iam:ListPolicies", - "iam:ListPolicyVersions", - "iam:GetPolicyVersion", - "iam:GetPolicy", - "iam:GetRole", - "iam:GetRolePolicy", - "iam:ListInstanceProfiles", - "iam:ListInstanceProfilesForRole", - "iam:ListRolePolicies", - "iam:ListRoles", - "iam:ListPolicies", - "iam:ListPolicyVersions", + "iam:CreatePolicy", + "iam:CreateRole", "iam:GetPolicy", "iam:GetPolicyVersion", "iam:GetRole", "iam:GetRolePolicy", + "iam:ListAttachedRolePolicies", "iam:ListGroupPolicies", "iam:ListGroups", "iam:ListInstanceProfiles", "iam:ListInstanceProfilesForRole", - "iam:ListRolePolicies", - "iam:ListRoles", "iam:ListPolicies", "iam:ListPolicyVersions", - "sns:*", - "s3:ListAllMyBuckets", + "iam:ListRolePolicies", + "iam:ListRoles", + "iam:PassRole", + "iam:PutRolePolicy", + "iam:TagRole", + "iam:TagPolicy", + "logs:*", + "route53:*", "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListAllMyBuckets", + "s3:ListBucket", + "s3:PutObject", + "servicediscovery:*", + "sns:*", + "ssm:DeleteParameter", + "ssm:DescribeParameters", + "ssm:GetParameter", + "ssm:GetParameters", + "ssm:ListTagsForResource", + "ssm:PutParameter" ], Resource = "*", }, @@ -93,6 +80,7 @@ resource "aws_iam_role_policy_attachment" "codebuild_all_permissions_attachment" policy_arn = aws_iam_policy.codebuild_all_permissions.arn role = aws_iam_role.this.name } + # CodeBuild project resource "aws_codebuild_project" "this" { name = var.name