diff --git a/.github/workflows/terraform-plan.yaml b/.github/workflows/terraform-plan.yaml index 1128c41..598e14a 100644 --- a/.github/workflows/terraform-plan.yaml +++ b/.github/workflows/terraform-plan.yaml @@ -13,7 +13,7 @@ jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on - runs-on: [ terraform-aws-image-pipeline ] + runs-on: [ ubuntu-latest ] env: AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" AWS_ACCESS_KEY_ID: "${{ vars.AWS_ACCESS_KEY_ID }}" @@ -28,11 +28,11 @@ jobs: ref: ${{ github.head_ref }} token: ${{ secrets.GH_TOKEN }} - - uses: CSVD/gh-actions-setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 16 - - uses: CSVD/gh-actions-setup-terraform@v2 + - uses: hashicorp/setup-terraform@v3.1.2 with: terraform_version: ${{ vars.terraform_version }} @@ -54,28 +54,14 @@ jobs: - name: Terraform Init id: init - - working-directory: ./examples - run: terraform init -upgrade - name: Terraform Validate id: validate - - working-directory: ./examples - run: terraform validate - - name: Terraform Plan - id: plan - - working-directory: ./examples - - run: terraform plan - continue-on-error: true - - name: Update Pull Request - uses: CSVD/gh-actions-github-script@v6 + uses: actions/github-script@v6 if: github.event_name == 'pull_request' with: github-token: ${{ secrets.GH_TOKEN }} diff --git a/.gitignore b/.gitignore index 2faf43d..4522103 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc +.tflog \ No newline at end of file diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 393131c..49a1a0b 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,50 +2,51 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "5.86.0" + version = "5.91.0" constraints = ">= 4.20.1" hashes = [ - "h1:dVxrQ67Ikqv/1/rfopK/wvCdETlUbQ6ZFuNOH+vEWqs=", - "zh:1587c6a0199dc33d066c13e1628bc0dd966d7d6740cb2007b636524a3ec99430", - "zh:15af46cc5bb43a37c24438cb3a36d44209a89d923ea4d4d631b56b1a89717b26", - "zh:166902101ac1cc8ec4f53e3bdcbab2eac7eb448b1c428c2e622adbf9ce1a679c", - "zh:284d116ac9d4a4de74cd1f52486f00e10bc400d9654f92a8990ea0093c43ff78", - "zh:4135e928f20d456172c8ab4ae3d4d8e411b6feddc94aaa1347c92469d52f1e61", - "zh:72b317d17182c3e0ee72f2851d25565d369cb6ee803b12adc9b6c6d3dbfca8d7", + "h1:rqkcSC4Ou2D7QZTrm/VU+71Ulqqwp8mU9jx3FVYnMCo=", + "zh:03ee14261b25aee94c735ed6ef7cce47900ab7bdf462335432ca034d0ba74ca2", + "zh:32a3759049c9c2cd041d1257cf16cb90a5ce586e1d0a6fe5f8ebd0ec1ba8e071", + "zh:334db69bc6d8643ec4ea432f0e54e851c2394bbe889cca29ca5029db0e4699e8", + "zh:39957a4a900f100ea8d85845a42164a44c9efea8559a9e74ab4f6a1193e20c3e", + "zh:8831396c764815eb367601a522c51c2e9e8fc38bcaa5f5e83f21de771778e9ba", + "zh:8e71ab68c27f909892a063f845d92faa487297ad9bbc67c77a67194e509781e6", + "zh:944df1084a7ea37a4feea0ee6654fd15891ef4829c5453bc149ffbcc0ab9bad7", + "zh:964391527624f2e66a4eb387ad0a30a1b67a896e9395b6d01353f2572723ea03", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9dd0e80964e215ff658b708be72ccda8a20f63af7eaebdd6f11eb0461633bb03", - "zh:a18e502c16b7b6b216b888eab9a5c66b1ed103847fce6985850e4fc9e364a3e8", - "zh:c239f12648d7f7bbadbf5db0b57aaa9429abe70b574975b581784b4f17b7ed79", - "zh:c5164ca8254b9973ee985a3841a4b1f776844c7dcbc112ab3a88a0096e7e2198", - "zh:d93ac58092c3fffc5ddc688b39721fbfacc353e8965001060a5a1ce934d97246", - "zh:e877f1be2ebe67a2d163b7488f47cff4c95aca9c541ddfa25ad16c6ecc98f6a8", - "zh:eb71af6dfdd2b5670b5b957397a576d6053587c75750c17acc105fb44ed806eb", - "zh:ff6aa4f88f8e789375391bc8c886c636fb3e4a45a3fd7dc291bca17c2b8d4184", + "zh:bb956c660185161e8ce1ed1dbf187c9f549d1779673fe798211dd5b02b98c737", + "zh:c237199ca8cd88f4aab4c673f848c77670b90d98a484fef6bcd31a71ff63d9b9", + "zh:c7522f6072f8ba29f4a6d0f994eda8a381ed2f4a41dbe44c4d989c44852cfe63", + "zh:d412a852ced01433c44f222952b60974f7c297a8a21bef62c9a627b050084134", + "zh:e420266b772041fa89e5868594ed21c8c3090d76b3ec0262054f768a7807f5a7", + "zh:ecfcc7844e9e01123920a4b0e667a4688654e3f22f00890ec80ddd78e7312eda", ] } provider "registry.terraform.io/hashicorp/random" { - version = "3.6.3" + version = "3.7.1" hashes = [ - "h1:Fnaec9vA8sZ8BXVlN3Xn9Jz3zghSETIKg7ch8oXhxno=", - "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", - "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", - "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", - "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", - "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", - "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "h1:/qtweZW2sk0kBNiQM02RvBXmlVdI9oYqRMCyBZ8XA98=", + "zh:3193b89b43bf5805493e290374cdda5132578de6535f8009547c8b5d7a351585", + "zh:3218320de4be943e5812ed3de995946056db86eb8d03aa3f074e0c7316599bef", + "zh:419861805a37fa443e7d63b69fb3279926ccf98a79d256c422d5d82f0f387d1d", + "zh:4df9bd9d839b8fc11a3b8098a604b9b46e2235eb65ef15f4432bde0e175f9ca6", + "zh:5814be3f9c9cc39d2955d6f083bae793050d75c572e70ca11ccceb5517ced6b1", + "zh:63c6548a06de1231c8ee5570e42ca09c4b3db336578ded39b938f2156f06dd2e", + "zh:697e434c6bdee0502cc3deb098263b8dcd63948e8a96d61722811628dce2eba1", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", - "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", - "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", - "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", - "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + "zh:a0b8e44927e6327852bbfdc9d408d802569367f1e22a95bcdd7181b1c3b07601", + "zh:b7d3af018683ef22794eea9c218bc72d7c35a2b3ede9233b69653b3c782ee436", + "zh:d63b911d618a6fe446c65bfc21e793a7663e934b2fef833d42d3ccd38dd8d68d", + "zh:fa985cd0b11e6d651f47cff3055f0a9fd085ec190b6dbe99bf5448174434cdea", ] } provider "registry.terraform.io/hashicorp/tls" { version = "4.0.6" hashes = [ + "h1:/sSdjHoiykrPdyBP1JE03V/KDgLXnHZhHcSOYIdDH/A=", "h1:dYSb3V94K5dDMtrBRLPzBpkMTPn+3cXZ/kIJdtFL+2M=", "zh:10de0d8af02f2e578101688fd334da3849f56ea91b0d9bd5b1f7a243417fdda8", "zh:37fc01f8b2bc9d5b055dc3e78bfd1beb7c42cfb776a4c81106e19c8911366297", diff --git a/README.md b/README.md index 06092c5..45d5cb7 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ | Name | Version | |------|---------| -| [aws](#provider\_aws) | 5.86.0 | -| [random](#provider\_random) | 3.6.3 | +| [aws](#provider\_aws) | 5.91.0 | +| [random](#provider\_random) | 3.7.1 | | [tls](#provider\_tls) | 4.0.6 | ## Modules @@ -32,6 +32,9 @@ | Name | Type | |------|------| +| [aws_iam_instance_profile.build_user_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.build_user_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.build_user_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | | [aws_key_pair.deployer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair) | resource | | [aws_secretsmanager_secret.secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | | [aws_secretsmanager_secret.ssh_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | @@ -55,9 +58,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [ami](#input\_ami) | n/a |
object({
instance_type = string
source_ami = string
})
| `null` | no | -| [ansible\_bucket](#input\_ansible\_bucket) | Ansible bucket details |
object({
name = string,
key = string
})
| `null` | no | -| [ansible\_repo](#input\_ansible\_repo) | Source of Ansible Repo |
object({
arn = optional(string)
repository_name = optional(string, "image-pipeline-ansible-playbooks")
branch = optional(string, "main")
})
| `null` | no | -| [ansible\_source\_type](#input\_ansible\_source\_type) | Type of source to be used for the Ansible CodePipeline | `string` | `"CodeCommit"` | no | +| [ansible\_bucket](#input\_ansible\_bucket) | Ansible bucket details |
object({
name = string,
key = string,
arn = string
})
| `null` | no | | [assets\_bucket\_name](#input\_assets\_bucket\_name) | Name of the S3 bucket used to store the deployment artifacts | `string` | `"image-pipeline-assets"` | no | | [build\_environment\_variables](#input\_build\_environment\_variables) | n/a |
list(object({
name = string
value = string
type = optional(string, "PLAINTEXT")
}))
| `null` | no | | [build\_project\_source](#input\_build\_project\_source) | Source Code Repo for Playbook | `string` | `"CODEPIPELINE"` | no | @@ -69,24 +70,23 @@ | [builder\_images](#input\_builder\_images) | n/a | `map(string)` | `{}` | no | | [builder\_type](#input\_builder\_type) | Type of codebuild run environment | `string` | `"LINUX_CONTAINER"` | no | | [codepipeline\_iam\_role\_name](#input\_codepipeline\_iam\_role\_name) | Name of the IAM role to be used by the Codepipeline | `string` | `"codepipeline-role"` | no | +| [create\_build\_user](#input\_create\_build\_user) | Whether to create a build user. Set to false if you want to use an existing user. | `bool` | `true` | no | | [create\_new\_role](#input\_create\_new\_role) | Whether to create a new IAM Role. Values are true or false. Defaulted to true always. | `bool` | `true` | no | | [docker\_build](#input\_docker\_build) | n/a | `bool` | `false` | no | | [extra\_parameters](#input\_extra\_parameters) | n/a | `map(string)` | `{}` | no | | [goss\_binary](#input\_goss\_binary) | GOSS Profile to be used for testing | `string` | `"goss-linux-amd64"` | no | -| [goss\_bucket](#input\_goss\_bucket) | Goss bucket details |
object({
name = string,
key = string
})
| `null` | no | +| [goss\_bucket](#input\_goss\_bucket) | Goss bucket details |
object({
name = string,
key = string,
})
| `null` | no | | [goss\_profile](#input\_goss\_profile) | GOSS Profile to be used for testing | `string` | `"goss"` | no | -| [goss\_repo](#input\_goss\_repo) | Source of Goss Repo |
object({
arn = optional(string)
repository_name = optional(string, "image-pipeline-goss-testing")
branch = optional(string, "main")
})
| `null` | no | -| [goss\_source\_type](#input\_goss\_source\_type) | Type of source to be used for the Goss CodePipeline | `string` | `"CodeCommit"` | no | | [image](#input\_image) | n/a |
object({
dest_tag = string
dest_docker_repo = string
source_image = string
source_tag = string
source_docker_repo = string
})
| `null` | no | | [image\_volume\_mapping](#input\_image\_volume\_mapping) | n/a |
list(object({
device_name = string
volume_size = number
volume_type = string
delete_on_termination = bool
encrypted = optional(bool, false)
iops = optional(number, null)
snapshot_id = optional(string, null)
throughput = optional(number, null)
virtual_name = optional(string, null)
kms_key_id = optional(string, null)
mount_path = optional(string, null)
}))
| `[]` | no | +| [instance\_profile](#input\_instance\_profile) | n/a | `string` | `null` | no | | [kms\_key\_id](#input\_kms\_key\_id) | n/a | `string` | `null` | no | | [nonmanaged\_parameters](#input\_nonmanaged\_parameters) | n/a | `list(string)` |
[
"dest_tag"
]
| no | -| [packer\_bucket](#input\_packer\_bucket) | Source bucket details |
object({
name = string,
key = string
})
| `null` | no | +| [packer\_bucket](#input\_packer\_bucket) | Source bucket details |
object({
name = string,
arn = string,
key = string
})
| `null` | no | | [packer\_config](#input\_packer\_config) | Name of Packer Config in Repo | `string` | `"build.pkr.hcl"` | no | -| [packer\_repo](#input\_packer\_repo) | Source of the Terraform Repo |
object({
arn = optional(string)
repository_name = optional(string, "linux-image-pipeline")
branch = optional(string, "main")
})
| `null` | no | -| [packer\_source\_type](#input\_packer\_source\_type) | Type of source to be used for the CodePipeline | `string` | `"CodeCommit"` | no | | [packer\_version](#input\_packer\_version) | Terraform CLI Version | `string` | `"1.10.3"` | no | | [parameter\_arns](#input\_parameter\_arns) | n/a | `list(string)` | `null` | no | +| [pip\_bucket](#input\_pip\_bucket) | Pip bucket details |
object({
name = string,
key = string,
})
| `null` | no | | [playbook](#input\_playbook) | n/a | `string` | `null` | no | | [project\_name](#input\_project\_name) | Unique name for this project | `string` | n/a | yes | | [required\_packages](#input\_required\_packages) | n/a |
list(object({
src = string
dest = string
}))
| `[]` | no | @@ -95,7 +95,6 @@ | [shared\_accounts](#input\_shared\_accounts) | n/a | `list(string)` | `null` | no | | [shared\_kms\_key\_arns](#input\_shared\_kms\_key\_arns) | n/a | `list(string)` | `[]` | no | | [ssh\_user](#input\_ssh\_user) | SSH username | `string` | `null` | no | -| [stage\_input](#input\_stage\_input) | Tags to be attached to the CodePipeline |
list(object({
name = string,
category = string,
owner = string,
provider = string,
input_artifacts = list(string),
output_artifacts = list(string)
}))
|
[
{
"category": "Build",
"input_artifacts": [
"SourceOutput",
"SourceAnsibleOutput"
],
"name": "build",
"output_artifacts": [
"BuildOutput"
],
"owner": "AWS",
"provider": "CodeBuild"
},
{
"category": "Build",
"input_artifacts": [
"SourceOutput",
"SourceGossOutput"
],
"name": "test",
"output_artifacts": [
"BuildTestOutput"
],
"owner": "AWS",
"provider": "CodeBuild"
}
]
| no | | [state](#input\_state) | n/a |
object({
bucket = string
key = string
region = string
dynamodb_table = string
})
| n/a | yes | | [terraform\_version](#input\_terraform\_version) | n/a | `string` | `"1.3.10"` | no | | [test\_project\_source](#input\_test\_project\_source) | Source Code Repo for Goss Testing Suite | `string` | `"CODEPIPELINE"` | no | @@ -111,11 +110,11 @@ | [codepipeline\_arn](#output\_codepipeline\_arn) | The ARN of the CodePipeline | | [codepipeline\_name](#output\_codepipeline\_name) | The Name of the CodePipeline | | [iam\_arn](#output\_iam\_arn) | The ARN of the IAM Role used by the CodePipeline | -| [kms\_arn](#output\_kms\_arn) | The ARN of the KMS key used in the codepipeline | +| [kms\_arn](#output\_kms\_arn) | The KMS key ARN used in the codepipeline | | [managed\_parameters](#output\_managed\_parameters) | n/a | +| [role\_name](#output\_role\_name) | The name of the IAM role used for build and pipeline operations | | [s3\_arn](#output\_s3\_arn) | The ARN of the S3 Bucket | | [s3\_bucket](#output\_s3\_bucket) | The Name of the S3 Bucket | | [sec\_group](#output\_sec\_group) | n/a | | [secrets](#output\_secrets) | n/a | -| [user](#output\_user) | n/a | \ No newline at end of file diff --git a/main.tf b/main.tf index b039af5..7c10e92 100644 --- a/main.tf +++ b/main.tf @@ -81,12 +81,10 @@ module "codepipeline_iam_role" { project_name = var.project_name create_new_role = var.create_new_role codepipeline_iam_role_name = var.create_new_role == true ? "${var.project_name}-codepipeline-role" : var.codepipeline_iam_role_name - packer_repo = var.packer_repo packer_bucket = var.packer_bucket - ansible_repo = var.ansible_repo ansible_bucket = var.ansible_bucket - goss_repo = var.goss_repo goss_bucket = var.goss_bucket + pip_bucket = var.pip_bucket image = var.image kms_key_arn = module.codepipeline_kms.arn shared_kms_key_arns = var.shared_kms_key_arns @@ -121,21 +119,12 @@ module "codepipeline_terraform" { project_name = var.project_name - packer_source_type = var.packer_source_type - packer_repo = var.packer_repo - packer_bucket = var.packer_bucket - - ansible_source_type = var.ansible_source_type - ansible_repo = var.ansible_repo - ansible_bucket = var.ansible_bucket - - goss_source_type = var.goss_source_type - goss_repo = var.goss_repo - goss_bucket = var.goss_bucket - + packer_bucket = var.packer_bucket + ansible_bucket = var.ansible_bucket + goss_bucket = var.goss_bucket + pip_bucket = var.pip_bucket s3_bucket_name = module.s3_artifacts_bucket.bucket codepipeline_role_arn = module.codepipeline_iam_role.role_arn - stages = var.stage_input kms_key_arn = module.codepipeline_kms.arn tags = { Project_Name = var.project_name @@ -168,8 +157,8 @@ resource "aws_iam_role" "build_user_role" { } resource "aws_iam_role_policy" "build_user_policy" { - name = "${var.project_name}-build-user-policy" - role = aws_iam_role.build_user_role.id + name = "${var.project_name}-build-user-policy" + role = aws_iam_role.build_user_role.id policy = local.build_user_iam_policy } diff --git a/modules/codebuild/templates/buildspec_build.yml b/modules/codebuild/templates/buildspec_build.yml index dae795d..3fe851f 100644 --- a/modules/codebuild/templates/buildspec_build.yml +++ b/modules/codebuild/templates/buildspec_build.yml @@ -9,6 +9,9 @@ phases: runtime-versions: python: 3.11 commands: + - cp "$${CODEBUILD_SRC_DIR_SourcePipConfigOutput}/pip.conf" /etc/pip.conf + - cp "$${CODEBUILD_SRC_DIR_SourcePipConfigOutput}/pip-cert.pem" /etc/pip-cert.pem + - echo "Installing required packages" - which pip3 || curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py - which pip3 || python3 get-pip.py --user - stat $(python -m site --user-base)/bin/ansible-playbook || python3 -m pip install --user ansible pywinrm diff --git a/modules/codepipeline/locals.tf b/modules/codepipeline/locals.tf new file mode 100644 index 0000000..d5363e4 --- /dev/null +++ b/modules/codepipeline/locals.tf @@ -0,0 +1,22 @@ +locals { + build_sources = ["SourceOutput", "SourceAnsibleOutput", "SourcePipConfigOutput"] + test_sources = ["SourceOutput", "SourceGossOutput"] + stages = [ + { + name = "build", + category = "Build", + owner = "AWS", + provider = "CodeBuild", + input_artifacts = local.build_sources, + output_artifacts = ["BuildOutput"] + }, + { + name = "test", + category = "Build", + owner = "AWS", + provider = "CodeBuild", + input_artifacts = local.test_sources, + output_artifacts = ["BuildTestOutput"] + }, + ] +} \ No newline at end of file diff --git a/modules/codepipeline/main.tf b/modules/codepipeline/main.tf index ef89724..4653ec9 100644 --- a/modules/codepipeline/main.tf +++ b/modules/codepipeline/main.tf @@ -22,23 +22,37 @@ resource "aws_codepipeline" "terraform_pipeline" { stage { name = "Source" + action { + name = "Download-Pip-Config" + category = "Source" + owner = "AWS" + version = "1" + provider = "S3" + namespace = "SourcePipConfig" + output_artifacts = ["SourcePipConfigOutput"] + run_order = 1 + + configuration = { + S3Bucket = var.pip_bucket.name + S3ObjectKey = var.pip_bucket.key + PollForSourceChanges = "false" + } + } + action { name = "Download-Packer-Template" category = "Source" owner = "AWS" version = "1" - provider = var.packer_source_type + provider = "S3" namespace = "SourceVariables" output_artifacts = ["SourceOutput"] run_order = 1 - configuration = var.packer_source_type == "CodeCommit" ? { - RepositoryName = var.packer_repo.repository_name - BranchName = var.packer_repo.branch - PollForSourceChanges = "false" - } : { + configuration = { S3Bucket = var.packer_bucket.name S3ObjectKey = var.packer_bucket.key + PollForSourceChanges = "false" } } @@ -47,21 +61,16 @@ resource "aws_codepipeline" "terraform_pipeline" { category = "Source" owner = "AWS" version = "1" - provider = var.ansible_source_type + provider = "S3" namespace = "SourceAnsible" output_artifacts = ["SourceAnsibleOutput"] run_order = 1 - configuration = merge(var.ansible_source_type == "CodeCommit" ? { - RepositoryName = var.ansible_repo.repository_name - BranchName = var.ansible_repo.branch - } : { + configuration = { S3Bucket = var.ansible_bucket.name S3ObjectKey = var.ansible_bucket.key - }, - { - PollForSourceChanges = "false" - }) + PollForSourceChanges = "false" + } } action { @@ -69,39 +78,36 @@ resource "aws_codepipeline" "terraform_pipeline" { category = "Source" owner = "AWS" version = "1" - provider = var.goss_source_type + provider = "S3" namespace = "SourceGoss" output_artifacts = ["SourceGossOutput"] run_order = 1 - configuration = var.goss_source_type == "CodeCommit" ? { - RepositoryName = var.goss_repo.repository_name - BranchName = var.goss_repo.branch - PollForSourceChanges = "false" - } : { + configuration = { S3Bucket = var.goss_bucket.name S3ObjectKey = var.goss_bucket.key + PollForSourceChanges = "false" } } } dynamic "stage" { - for_each = var.stages + for_each = local.stages content { name = title(stage.value["name"]) action { category = stage.value["category"] - name = "Action-${stage.value["name"]}" + name = "${var.project_name}-${stage.value["name"]}" owner = stage.value["owner"] provider = stage.value["provider"] input_artifacts = lookup(stage.value, "input_artifacts", "") != "" ? stage.value["input_artifacts"] : null output_artifacts = lookup(stage.value, "output_artifacts", "") != "" ? stage.value["output_artifacts"] : null version = "1" - run_order = index(var.stages, stage.value) + 2 + run_order = index(local.stages, stage.value) + 2 configuration = { - ProjectName = stage.value["provider"] == "CodeBuild" ? "${var.project_name}-${stage.value["name"]}" : null + ProjectName = "${var.project_name}-${stage.value["name"]}" PrimarySource = "SourceOutput" } } diff --git a/modules/codepipeline/outputs.tf b/modules/codepipeline/outputs.tf index 3bbbf07..66384fb 100644 --- a/modules/codepipeline/outputs.tf +++ b/modules/codepipeline/outputs.tf @@ -19,4 +19,12 @@ output "arn" { description = "The arn of the CodePipeline" } +output build_sources { + value = local.build_sources + description = "The build sources for the CodePipeline" +} +output test_sources { + value = local.test_sources + description = "The test sources for the CodePipeline" +} \ No newline at end of file diff --git a/modules/codepipeline/variables.tf b/modules/codepipeline/variables.tf index 8a7aa2d..2dfc67d 100644 --- a/modules/codepipeline/variables.tf +++ b/modules/codepipeline/variables.tf @@ -31,24 +31,6 @@ variable "tags" { type = map(any) } -variable "stages" { - description = "List of Map containing information about the stages of the CodePipeline" - type = list(object({ - name = string, - category = string, - owner = string, - provider = string, - input_artifacts = list(string), - output_artifacts = list(string) - })) -} - -variable "packer_source_type" { - description = "Type of source to be used for the CodePipeline" - type = string - default = "CodeCommit" -} - variable "packer_bucket" { description = "Source bucket details" type = object({ @@ -58,22 +40,6 @@ variable "packer_bucket" { default = null } -variable "packer_repo" { - type = object({ - repository_name = optional(string, "linux-image-pipeline") - branch = optional(string, "main") - }) - description = "Source of the Terraform Repo" - default = null -} - - -variable "ansible_source_type" { - description = "Type of source to be used for the Ansible CodePipeline" - type = string - default = "CodeCommit" -} - variable "ansible_bucket" { description = "Ansible bucket details" type = object({ @@ -83,36 +49,20 @@ variable "ansible_bucket" { default = null } -variable "ansible_repo" { - type = object({ - repository_name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") - }) - description = "Source of Ansible Repo" - default = null -} - - -variable "goss_source_type" { - description = "Type of source to be used for the Goss CodePipeline" - type = string - default = "CodeCommit" -} - -variable "goss_repo" { +variable "goss_bucket" { + description = "Goss bucket details" type = object({ - repository_name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") + name = string, + key = string }) - description = "Source of Ansible Repo" - default = null + default = null } -variable "goss_bucket" { - description = "Goss bucket details" +variable "pip_bucket" { type = object({ name = string, key = string }) - default = null + description = "Ansible bucket details" + default = null } \ No newline at end of file diff --git a/modules/iam-role/main.tf b/modules/iam-role/main.tf index e176040..28eade1 100644 --- a/modules/iam-role/main.tf +++ b/modules/iam-role/main.tf @@ -37,15 +37,17 @@ resource "aws_iam_role" "codepipeline_role" { } locals { - codecommit_repos = concat( - var.packer_repo == null ? [] : [var.packer_repo.arn], - var.ansible_repo == null ? [] : [var.ansible_repo.arn], - var.goss_repo == null ? [] : [var.goss_repo.arn] - ) - codecommit_repo_count = length(local.codecommit_repos) - # Construct bucket ARNs directly since we know the bucket name - assets_bucket_arn = "arn:${data.aws_partition.current.partition}:s3:::${var.goss_bucket.name}" + assets_bucket_arns = distinct([ + "arn:${data.aws_partition.current.partition}:s3:::${var.goss_bucket.name}", + "arn:${data.aws_partition.current.partition}:s3:::${var.goss_bucket.name}/*", + "arn:${data.aws_partition.current.partition}:s3:::${var.ansible_bucket.name}", + "arn:${data.aws_partition.current.partition}:s3:::${var.ansible_bucket.name}/*", + "arn:${data.aws_partition.current.partition}:s3:::${var.packer_bucket.name}", + "arn:${data.aws_partition.current.partition}:s3:::${var.packer_bucket.name}/*", + "arn:${data.aws_partition.current.partition}:s3:::${var.pip_bucket.name}", + "arn:${data.aws_partition.current.partition}:s3:::${var.pip_bucket.name}/*" + ]) } data "aws_iam_policy_document" "codepipeline_policy" { @@ -67,15 +69,8 @@ data "aws_iam_policy_document" "codepipeline_policy" { "${var.s3_bucket_arn}/*", "arn:${data.aws_partition.current.partition}:s3:::${var.state.bucket}/*" ], - var.goss_bucket == null ? [] : [ - "${local.assets_bucket_arn}/*" - ], - var.ansible_bucket == null ? [] : [ - "${local.assets_bucket_arn}/*" - ], - var.packer_bucket == null ? [] : [ - "${local.assets_bucket_arn}/*" - ])) + local.assets_bucket_arns + )) } statement { effect = "Allow" @@ -159,28 +154,6 @@ data "aws_iam_policy_document" "codepipeline_policy" { ] } - dynamic "statement" { - for_each = local.codecommit_repo_count > 0 ? ["*"] : [] - content { - effect = "Allow" - actions = [ - "codecommit:GitPull", - "codecommit:GitPush", - "codecommit:GetBranch", - "codecommit:CreateCommit", - "codecommit:ListRepositories", - "codecommit:BatchGetCommits", - "codecommit:BatchGetRepositories", - "codecommit:GetCommit", - "codecommit:GetRepository", - "codecommit:GetUploadArchiveStatus", - "codecommit:ListBranches", - "codecommit:UploadArchive" - ] - resources = local.codecommit_repos - } - } - statement { effect = "Allow" actions = [ diff --git a/modules/iam-role/variables.tf b/modules/iam-role/variables.tf index 137fe7b..dca2c77 100644 --- a/modules/iam-role/variables.tf +++ b/modules/iam-role/variables.tf @@ -45,17 +45,6 @@ variable "create_new_role" { default = true } - - -variable "ansible_repo" { - type = object({ - arn = string, - name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") - }) - description = "Source of Ansible Repo" -} - variable "ansible_bucket" { type = object({ name = string, @@ -65,16 +54,6 @@ variable "ansible_bucket" { default = null } - -variable "goss_repo" { - type = object({ - arn = string, - name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") - }) - description = "Source of Ansible Repo" -} - variable "goss_bucket" { type = object({ name = string, @@ -84,16 +63,16 @@ variable "goss_bucket" { default = null } -variable "packer_repo" { +variable "packer_bucket" { type = object({ - arn = string, - name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") + name = string, + key = string }) - description = "Source of Ansible Repo" + description = "Ansible bucket details" + default = null } -variable "packer_bucket" { +variable "pip_bucket" { type = object({ name = string, key = string @@ -102,8 +81,6 @@ variable "packer_bucket" { default = null } - - variable "vpc_config" { default = null type = object({ diff --git a/parameters_and_secrets.tf b/parameters_and_secrets.tf index a280f3d..c5f2267 100644 --- a/parameters_and_secrets.tf +++ b/parameters_and_secrets.tf @@ -74,7 +74,7 @@ locals { nonsensitive_parameters = tomap( { for k, v in local.ssm_parameters : (issensitive(k) ? nonsensitive(k) : k) => (issensitive(v) ? nonsensitive(v) : v) - if ! contains(var.nonmanaged_parameters, issensitive(k) ? nonsensitive(k) : k) + if !contains(var.nonmanaged_parameters, issensitive(k) ? nonsensitive(k) : k) } ) } diff --git a/variables.tf b/variables.tf index eabce48..211fd44 100644 --- a/variables.tf +++ b/variables.tf @@ -27,37 +27,6 @@ variable "codepipeline_iam_role_name" { # } -variable "stage_input" { - description = "Tags to be attached to the CodePipeline" - type = list(object({ - name = string, - category = string, - owner = string, - provider = string, - input_artifacts = list(string), - output_artifacts = list(string) - })) - default = [ - { - name = "build", - category = "Build", - owner = "AWS", - provider = "CodeBuild", - input_artifacts = ["SourceOutput", "SourceAnsibleOutput"], - output_artifacts = ["BuildOutput"] - }, - { - name = "test", - category = "Build", - owner = "AWS", - provider = "CodeBuild", - input_artifacts = ["SourceOutput", "SourceGossOutput"], - output_artifacts = ["BuildTestOutput"] - }, - ] -} - - variable "build_projects" { description = "List of Names of the CodeBuild projects to be created" type = list(object({ @@ -142,79 +111,41 @@ variable "packer_config" { default = "build.pkr.hcl" } -variable "packer_source_type" { - description = "Type of source to be used for the CodePipeline" - type = string - default = "CodeCommit" -} - variable "packer_bucket" { type = object({ name = string, + arn = string, key = string }) description = "Source bucket details" default = null } -variable "packer_repo" { - type = object({ - arn = optional(string) - repository_name = optional(string, "linux-image-pipeline") - branch = optional(string, "main") - }) - description = "Source of the Terraform Repo" - default = null -} - -variable "ansible_source_type" { - description = "Type of source to be used for the Ansible CodePipeline" - type = string - default = "CodeCommit" -} - -variable "ansible_repo" { - type = object({ - arn = optional(string) - repository_name = optional(string, "image-pipeline-ansible-playbooks") - branch = optional(string, "main") - }) - description = "Source of Ansible Repo" - default = null -} - variable "ansible_bucket" { type = object({ name = string, - key = string + key = string, + arn = string }) description = "Ansible bucket details" default = null } - -variable "goss_source_type" { - description = "Type of source to be used for the Goss CodePipeline" - type = string - default = "CodeCommit" -} - -variable "goss_bucket" { +variable "pip_bucket" { type = object({ name = string, - key = string + key = string, }) - description = "Goss bucket details" + description = "Pip bucket details" default = null } -variable "goss_repo" { +variable "goss_bucket" { type = object({ - arn = optional(string) - repository_name = optional(string, "image-pipeline-goss-testing") - branch = optional(string, "main") + name = string, + key = string, }) - description = "Source of Goss Repo" + description = "Goss bucket details" default = null }