This repository contains all the code and information to successfully create a pipeline to automatically deploy infrastructure via Terraform scripts on AWS China.
By going through all the described steps, the following resources will be created within your AWS China account:
- S3 Buckets:
- States Bucket: Contains the Terraform states. SSE-S3 encryption is enabled. Versioning is enabled which allows accessing previous states.
- Assets Bucket: Will be used to store assets used by Terraform since we have difficulties in China to directly download the latest versions of Terraform and the required AWS Provider via the public internet from the official HashiCorp servers. SSE-S3 encryption is enabled.
- Artifacts Bucket: Contains the artifacts generated by CodeBuild. SSE-S3 encryption is enabled.
- DynamoDB Locks Table: Contains the Terraform lock states.
- IAM Policy: A general IAM policy with full permissions used for all infrastructure operations.
- IAM Roles:
- Terraform Role: Assumed by Terraform to deploy the infrastructure.
- CodeBuild Role: Assumed by CodeBuild to operate successfully.
- CodePipeline Role: Assumed by CodePipeline to operate successfully.
- CodeCommit Repository: Will be used to store this repositories code and all future code used for the infrastructure. The CodePipeline will pull the latest Terraform scripts from this repository.
- CodeBuild Projects:
- Terraform Plan Project: Validates and plans the infrastructure based on the latest version within the CodeCommit repository. Linux Environment. Using
aws/codebuild/standard:2.0
Image. Using 3 GB memory, 2 vCPUs. - Terraform Apply Project: Applies the infrastructure based on the latest version within the CodeCommit repository. Linux Environment. Using
aws/codebuild/standard:2.0
Image. Using 3 GB memory, 2 vCPUs.
- Terraform Plan Project: Validates and plans the infrastructure based on the latest version within the CodeCommit repository. Linux Environment. Using
- CodePipeline: Orchestrates the entire deployment process and consists of the following four phases:
- get-source: Loads the updated source from CodeCommit
- terraform-plan: Validates and plans the infrastructure
- manual-approval: Waits for manual approval before deploying the infrastructure
- terraform-apply: Deploys the infrastructure
- VPC: An example VPC to demonstrate the working Terraform deployment pipeline.
In order to successfully create the pipeline and all required components via the in this repository provided Terraform scripts, a few preparations are necessary.
- Install Terraform on your local machine (v1.4.4 or higher).
- An AWS China account (Your AWS International account will not work since AWS China is using a completely independent infrastructure).
- An IAM User with sufficient permissions (for example the
AdministratorAccess
policy) to create the pipeline and all required components during the initial bootstrapping phase.
In order to get the full deployment pipeline up and running, you have to perform the following steps.
Clone this repository into your local development environment.
Adjust the variables in the main.tf
file. In the provider
block you can set the region to your preferred AWS China Region (possible values are cn-northwest-1
and cn-north-1
):
region = "cn-northwest-1"
Change the variables within the bootstrap
module as necessary. Ensure that some names must be globally unique within AWS China (for example the S3 Bucket names).
infrastructure_states_bucket_name = "infrastructure-states"
infrastructure_locks_table_name = "infrastructure-locks"
infrastructure_assets_bucket_name = "infrastructure-assets"
infrastructure_artifacts_bucket_name = "infrastructure-artifacts"
infrastructure_repository_name = "infrastructure-repository"
infrastructure_terraform_plan_project_name = "terraform-plan"
infrastructure_terraform_apply_project_name = "terraform-apply"
infrastructure_terraform_version = "1.4.4"
infrastructure_terraform_aws_provider_version = "4.24.0"
infrastructure_pipeline_name = "infrastructure-pipeline"
Run the following command within the folder which contains the files of this cloned repository:
terraform init
Since the entire deployment process will run inside a Linux environment, ensure that you lock the linux_amd64
platform within your Terraform lock file by running the following command:
terraform providers lock -platform=linux_amd64
Otherwise, Terraform will be not able to initialize if you are using another platform like Windows locally.
Perform the initial deployment of the entire pipeline into AWS China by running the following commands and confirm the final action with a yes
:
terraform plan
terraform apply
Now that the S3 Bucket and the DynamoDB table for the Terraform backend got successfully deployed into your AWS China account, it is time to update the Terraform configuration. Uncomment the following lines inside the main.tf
file:
backend "s3" {
bucket = "infrastructure-states"
key = "infrastructure.state"
region = "cn-northwest-1"
dynamodb_table = "infrastructure-locks"
encrypt = true
}
Ensure that the values for bucket
, region
and dynamodb_table
are matching the resources and region which got defined before in Step 2.
Run again the following command to migrate the existing local state into your S3 backend and confirm the action with a yes
:
terraform init
One of the big problems within AWS China are connectivity issues to everything hosted outside of China. It is very likely that Terraform will have difficulties to directly download the latest versions of Terraform and the required AWS Provider via the public internet from the official HashiCorp servers while trying to perform operations during a CodeBuild project. To avoid this, we will download the required assets in advance and upload them to the assets bucket which got deployed into your AWS China account during Step 5 afterwards.
Ensure that the downloaded versions are for the linux_amd64
platform and matching the versions which you defined in Step 2 inside of the infrastructure_terraform_version
and infrastructure_terraform_aws_provider_version
variables.
You can download the required assets from here:
- Terraform: https://releases.hashicorp.com/terraform/1.4.4/terraform_1.4.4_linux_amd64.zip
- Terraform AWS Provider: https://releases.hashicorp.com/terraform-provider-aws/4.24.0/terraform-provider-aws_4.24.0_linux_amd64.zip
Important: Again, ensure that you use the correct version and platform!
After downloading the assets, you have to upload them to the assets bucket which got deployed into your AWS China account during Step 5. The location of the asset must follow a specific schema, for example:
- Terraform:
- File Name: terraform_1.4.4_linux_amd64.zip
- Bucket Location: s3://infrastructure-assets/terraform/1.4.4/terraform_1.4.4_linux_amd64.zip
- Terraform AWS Provider:
- File Name: terraform-provider-aws_4.24.0_linux_amd64.zip
- Bucket Location: s3://infrastructure-assets/providers/registry.terraform.io/hashicorp/aws/terraform-provider-aws_4.24.0_linux_amd64.zip
Again, ensure that the versions are consistent with the values used during Step 2 and Step 8.
We are almost done! One final modification is the adjustment of the AWS Provider configuration to ensure that Terraform is assuming an IAM role with sufficient permissions while deploying the infrastructure during a CodeBuild project. Uncomment the following lines inside the main.tf
file and ensure that you are replacing 001122334455
with the Account ID of your AWS China account:
assume_role {
role_arn = "arn:aws-cn:iam::001122334455:role/infrastructure-terraform-role"
}
Now it is time to upload all of your code into your CodeCommit repository. Initialize and configure a new local Git repository and commit and push your code into the repository afterwards using the commands below. Ensure that you are using the main
branch and the correct origin
based on your defined repository name during Step 2.
git init --initial-branch=main
git config credential.UseHttpPath true
git remote add origin https://git-codecommit.cn-northwest-1.amazonaws.com.cn/v1/repos/infrastructure-repository
git add .
git commit -m "Initial commit"
git push --set-upstream origin main
And that's it! Your AWS China Terraform Deployment Pipeline should now work properly. To verify that everything is working, log into your AWS China Management Console, switch to CodePipeline service and check the current status. If everything goes well, then your CodePipeline will transition to the manual-approval
stage after a while. Since we didn't apply any further changes to the infrastructure since the last deployment from the local machine so far, everything should be up to date. So just go ahead and approve the current stage to move into the final terraform-apply
stage which finishes the execution.
Now it is time to add your own infrastructure! I created an additional module called infrastructure
in which you can place your custom resources. Inside the /modules/infrastructure/vpc.tf
file you can find the definition for an example VPC which you can uncomment. If you commit and push the changes into your repository, the pipeline will detect the modifications, verifies them and applies them after a manual approval.
Feel free to play around with your own resources or add additional modules to build a more complex infrastructure!