目次
- EKSクラスタの作成
- ECRレポジトリの作成
- IAMロールの作成
- Cluster Essentialsのインストール
- Tanzu Application Platformのインストール
- Workloadの作成
- Let's Encrypt (HTTP01 challenge)のClusterIssuerを作成
- (Optional) Metrics Serverのインストール
- Local Source Proxy
- Bitnami ServiceでPostgreSQLを動的プロビジョニング
- App Live View
- AWS ServicesでRDSの動的プロビジョニング
- Workloadのソースコード取得元にAWS CodeCommitを使用
- EnvoyのLoad Balancerに対するInboundのIP制限
- アンインストール
EKSクラスタの作成
brew install awscli
brew install eksctl
export AWS_ACCESS_KEY_ID=*****
export AWS_SECRET_ACCESS_KEY=*****
export AWS_SESSION_TOKEN=****
cat <<EOF > eks-cluster-config.yaml
---
kind: ClusterConfig
apiVersion: eksctl.io/v1alpha5
metadata:
name: tap-eks
region: ap-northeast-1
version: "1.28"
managedNodeGroups:
- name: tap-eks-ng-1
minSize: 3
maxSize: 3
desiredCapacity: 3
volumeSize: 200
maxPodsPerNode: 110
instanceType: m5.xlarge
spot: false # <--- If you want to use spot instances, set true. If you intend to use sslip.io for the shared.ingress_domain below, I recommend avoiding the use of spot instances.
ssh:
allow: true
publicKeyPath: ~/.ssh/id_rsa.pub
addons:
- name: aws-ebs-csi-driver
wellKnownPolicies:
ebsCSIController: true
iam:
withOIDC: true
---
EOF
eksctl create cluster -f eks-cluster-config.yaml
$ kubectl get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-192-168-19-134.ap-northeast-1.compute.internal Ready <none> 5m31s v1.28.3-eks-e71965b 192.168.19.134 35.78.100.84 Amazon Linux 2 5.10.199-190.747.amzn2.x86_64 containerd://1.7.3
ip-192-168-39-153.ap-northeast-1.compute.internal Ready <none> 5m32s v1.28.3-eks-e71965b 192.168.39.153 54.199.122.212 Amazon Linux 2 5.10.199-190.747.amzn2.x86_64 containerd://1.7.3
ip-192-168-79-97.ap-northeast-1.compute.internal Ready <none> 5m31s v1.28.3-eks-e71965b 192.168.79.97 43.207.126.145 Amazon Linux 2 5.10.199-190.747.amzn2.x86_64 containerd://1.7.3
$ kubectl get nodes -o=custom-columns='NAME:.metadata.name,INSTANCE-TYPE:.metadata.labels.beta\.kubernetes\.io/instance-type,CAPACITY-TYPE:.metadata.labels.eks\.amazonaws\.com/capacityType,ZONE:.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone'
NAME INSTANCE-TYPE CAPACITY-TYPE ZONE
ip-192-168-19-134.ap-northeast-1.compute.internal m5.xlarge ON_DEMAND ap-northeast-1c
ip-192-168-39-153.ap-northeast-1.compute.internal m5.xlarge ON_DEMAND ap-northeast-1a
ip-192-168-79-97.ap-northeast-1.compute.internal m5.xlarge ON_DEMAND ap-northeast-1d
ECRレポジトリの作成
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export AWS_REGION=ap-northeast-1
export EKS_CLUSTER_NAME=tap-eks
aws ecr create-repository --repository-name tap-images --region $AWS_REGION
aws ecr create-repository --repository-name tap-build-service --region $AWS_REGION
aws ecr create-repository --repository-name full-deps-package-repo --region $AWS_REGION
aws ecr create-repository --repository-name tap-lsp --region $AWS_REGION
aws ecr create-repository --repository-name tanzu-cluster-essentials --region $AWS_REGION
IAMロールの作成
# Retrieve the OIDC endpoint from the Kubernetes cluster and store it for use in the policy.
export OIDCPROVIDER=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --region $AWS_REGION --output json | jq '.cluster.identity.oidc.issuer' | tr -d '"' | sed 's/https:\/\///')
cat << EOF > build-service-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDCPROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDCPROVIDER}:aud": "sts.amazonaws.com"
},
"StringLike": {
"${OIDCPROVIDER}:sub": [
"system:serviceaccount:kpack:controller",
"system:serviceaccount:build-service:dependency-updater-controller-serviceaccount"
]
}
}
}
]
}
EOF
cat << EOF > build-service-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecr:DescribeRegistry",
"ecr:GetAuthorizationToken",
"ecr:GetRegistryPolicy",
"ecr:PutRegistryPolicy",
"ecr:PutReplicationConfiguration",
"ecr:DeleteRegistryPolicy"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "TAPEcrBuildServiceGlobal"
},
{
"Action": [
"ecr:DescribeImages",
"ecr:ListImages",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:BatchGetRepositoryScanningConfiguration",
"ecr:DescribeImageReplicationStatus",
"ecr:DescribeImageScanFindings",
"ecr:DescribeRepositories",
"ecr:GetDownloadUrlForLayer",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:GetRegistryScanningConfiguration",
"ecr:GetRepositoryPolicy",
"ecr:ListTagsForResource",
"ecr:TagResource",
"ecr:UntagResource",
"ecr:BatchDeleteImage",
"ecr:BatchImportUpstreamImage",
"ecr:CompleteLayerUpload",
"ecr:CreatePullThroughCacheRule",
"ecr:CreateRepository",
"ecr:DeleteLifecyclePolicy",
"ecr:DeletePullThroughCacheRule",
"ecr:DeleteRepository",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:PutImageScanningConfiguration",
"ecr:PutImageTagMutability",
"ecr:PutLifecyclePolicy",
"ecr:PutRegistryScanningConfiguration",
"ecr:ReplicateImage",
"ecr:StartImageScan",
"ecr:StartLifecyclePolicyPreview",
"ecr:UploadLayerPart",
"ecr:DeleteRepositoryPolicy",
"ecr:SetRepositoryPolicy"
],
"Resource": [
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/full-deps-package-repo",
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/tap-build-service",
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/tap-images"
],
"Effect": "Allow",
"Sid": "TAPEcrBuildServiceScoped"
}
]
}
EOF
cat << EOF > workload-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecr:DescribeRegistry",
"ecr:GetAuthorizationToken",
"ecr:GetRegistryPolicy",
"ecr:PutRegistryPolicy",
"ecr:PutReplicationConfiguration",
"ecr:DeleteRegistryPolicy"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "TAPEcrWorkloadGlobal"
},
{
"Action": [
"ecr:DescribeImages",
"ecr:ListImages",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:BatchGetRepositoryScanningConfiguration",
"ecr:DescribeImageReplicationStatus",
"ecr:DescribeImageScanFindings",
"ecr:DescribeRepositories",
"ecr:GetDownloadUrlForLayer",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:GetRegistryScanningConfiguration",
"ecr:GetRepositoryPolicy",
"ecr:ListTagsForResource",
"ecr:TagResource",
"ecr:UntagResource",
"ecr:BatchDeleteImage",
"ecr:BatchImportUpstreamImage",
"ecr:CompleteLayerUpload",
"ecr:CreatePullThroughCacheRule",
"ecr:CreateRepository",
"ecr:DeleteLifecyclePolicy",
"ecr:DeletePullThroughCacheRule",
"ecr:DeleteRepository",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:PutImageScanningConfiguration",
"ecr:PutImageTagMutability",
"ecr:PutLifecyclePolicy",
"ecr:PutRegistryScanningConfiguration",
"ecr:ReplicateImage",
"ecr:StartImageScan",
"ecr:StartLifecyclePolicyPreview",
"ecr:UploadLayerPart",
"ecr:DeleteRepositoryPolicy",
"ecr:SetRepositoryPolicy"
],
"Resource": [
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/full-deps-package-repo",
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/tanzu-application-platform/*"
],
"Effect": "Allow",
"Sid": "TAPEcrWorkloadScoped"
}
]
}
EOF
cat << EOF > workload-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDCPROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"${OIDCPROVIDER}:sub": "system:serviceaccount:*:default",
"${OIDCPROVIDER}:aud": "sts.amazonaws.com"
}
}
}
]
}
EOF
cat << EOF > local-source-proxy-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDCPROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDCPROVIDER}:aud": "sts.amazonaws.com"
},
"StringLike": {
"${OIDCPROVIDER}:sub": [
"system:serviceaccount:tap-local-source-system:proxy-manager"
]
}
}
}
]
}
EOF
cat << EOF > local-source-proxy-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "TAPLSPGlobal"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:ListTagsForResource",
"ecr:DescribeImageScanFindings",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": [
"arn:aws:ecr:${AWS_REGION}:${AWS_ACCOUNT_ID}:repository/tap-lsp"
],
"Sid": "TAPLSPScoped"
}
]
}
EOF
aws iam create-role --role-name tap-build-service --assume-role-policy-document file://build-service-trust-policy.json
aws iam put-role-policy --role-name tap-build-service --policy-name tapBuildServicePolicy --policy-document file://build-service-policy.json
aws iam create-role --role-name tap-workload --assume-role-policy-document file://workload-trust-policy.json
aws iam put-role-policy --role-name tap-workload --policy-name tapWorkload --policy-document file://workload-policy.json
aws iam create-role --role-name tap-local-source-proxy --assume-role-policy-document file://local-source-proxy-trust-policy.json
aws iam put-role-policy --role-name tap-local-source-proxy --policy-name tapLocalSourcePolicy --policy-document file://local-source-proxy-policy.json
Cluster Essentialsのインストール
IMGPKG_REGISTRY_HOSTNAME=registry.tanzu.vmware.com \
IMGPKG_REGISTRY_USERNAME=$TANZUNET_USERNAME \
IMGPKG_REGISTRY_PASSWORD=$TANZUNET_PASSWORD \
imgpkg copy \
-b registry.tanzu.vmware.com/tanzu-cluster-essentials/cluster-essentials-bundle:1.7.2 \
--to-tar cluster-essentials-bundle-1.7.2.tar \
--include-non-distributable-layers
ECR_REPO=$(aws ecr describe-repositories --region ap-northeast-1 --query 'repositories[?repositoryName==`tanzu-cluster-essentials`].repositoryUri' --output text)
aws ecr get-login-password --region ${AWS_REGION} | docker login ${ECR_REPO} -u AWS --password-stdin
imgpkg copy \
--tar cluster-essentials-bundle-1.7.2.tar \
--to-repo ${ECR_REPO} \
--include-non-distributable-layers
pivnet download-product-files --product-slug='tanzu-cluster-essentials' --release-version='1.7.2' --glob='tanzu-cluster-essentials-darwin-amd64-*'
mkdir -p tanzu-cluster-essentials
tar -xvf tanzu-cluster-essentials-*.tgz -C tanzu-cluster-essentials
cd tanzu-cluster-essentials
INSTALL_BUNDLE=${ECR_REPO}:1.7.2 \
INSTALL_REGISTRY_HOSTNAME=dummy.example.com \
INSTALL_REGISTRY_USERNAME=dummy \
INSTALL_REGISTRY_PASSWORD=dummy \
./install.sh --yes
cd ..
Tanzu Application Platformのインストール
IMGPKG_REGISTRY_HOSTNAME=registry.tanzu.vmware.com \
IMGPKG_REGISTRY_USERNAME=$TANZUNET_USERNAME \
IMGPKG_REGISTRY_PASSWORD=$TANZUNET_PASSWORD \
imgpkg copy \
-b registry.tanzu.vmware.com/tanzu-application-platform/tap-packages:1.7.3 \
--to-tar tap-bundle-1.7.3.tar \
--include-non-distributable-layers
ECR_REPO=$(aws ecr describe-repositories --region ap-northeast-1 --query 'repositories[?repositoryName==`tap-images`].repositoryUri' --output text)
aws ecr get-login-password --region ${AWS_REGION} | docker login ${ECR_REPO} -u AWS --password-stdin
imgpkg copy \
--concurrency 1 \
--tar tap-bundle-1.7.3.tar \
--to-repo ${ECR_REPO} \
--include-non-distributable-layers
brew install vmware-tanzu/tanzu/tanzu-cli
tanzu plugin install --group vmware-tap/default:v1.7.3
kubectl create ns tap-install
tanzu package repository add tanzu-tap-repository \
--url ${ECR_REPO}:1.7.3 \
--namespace tap-install
aws ec2 allocate-address --region ${AWS_REGION} > envoy-eip-1.json
aws ec2 create-tags --resources $(cat envoy-eip-1.json | jq -r .AllocationId) --region ${AWS_REGION} --tags Key=Name,Value=envoy-ip-1
aws ec2 allocate-address --region ${AWS_REGION} > envoy-eip-2.json
aws ec2 create-tags --resources $(cat envoy-eip-2.json | jq -r .AllocationId) --region ${AWS_REGION} --tags Key=Name,Value=envoy-ip-2
aws ec2 allocate-address --region ${AWS_REGION} > envoy-eip-3.json
aws ec2 create-tags --resources $(cat envoy-eip-3.json | jq -r .AllocationId) --region ${AWS_REGION} --tags Key=Name,Value=envoy-ip-3
cat << EOF > tap-values.yaml
---
shared:
ingress_domain: tap.$(cat envoy-eip-1.json | jq -r .PublicIp).sslip.io
ceip_policy_disclosed: true
profile: full
supply_chain: testing_scanning
ootb_supply_chain_testing_scanning:
registry:
server: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
# The prefix of the ECR repository. Workloads will need
# two repositories created:
#
# tanzu-application-platform/<workloadname>-<namespace>
# tanzu-application-platform/<workloadname>-<namespace>-bundle
repository: tanzu-application-platform
contour:
infrastructure_provider: aws
envoy:
workload:
type: Deployment
replicas: 2
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-eip-allocations: $(cat envoy-eip-1.json | jq -r .AllocationId),$(cat envoy-eip-2.json | jq -r .AllocationId),$(cat envoy-eip-3.json | jq -r .AllocationId)
aws:
LBType: nlb
contour:
replicas: 1
configFileContents:
accesslog-format: json
buildservice:
kp_default_repository: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/tap-build-service
kp_default_repository_aws_iam_role_arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/tap-build-service
exclude_dependencies: true
local_source_proxy:
repository: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/tap-lsp
push_secret:
aws_iam_role_arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/tap-local-source-proxy
ootb_templates:
iaas_auth: true
springboot_conventions:
autoConfigureActuators: true
tap_gui:
app_config:
auth:
allowGuestAccess: true
customize:
features:
supplyChain:
enableTriageUI: true
metadata_store:
ns_for_export_app_cert: "*"
app_service_type: ClusterIP
pg_req_cpu: "200m"
pg_req_memory: "200Mi"
namespace_provisioner:
aws_iam_role_arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/tap-workload
cnrs:
allow_manual_configmap_update: false
# 以下リソース節約用
lite:
enable: true
pdb:
enable: false
cartographer:
cartographer:
resources:
requests:
cpu: 100m
memory: 200Mi
crossplane:
resourcesCrossplane:
requests:
cpu: 100m
memory: 200Mi
resourcesRBACManager:
requests:
cpu: 100m
memory: 200Mi
excluded_packages:
- policy.apps.tanzu.vmware.com
- sso.apps.tanzu.vmware.com
- api-portal.tanzu.vmware.com
EOF
tanzu package install tap -p tap.tanzu.vmware.com -v 1.7.3 --values-file tap-values.yaml -n tap-install
IMGPKG_REGISTRY_HOSTNAME=registry.tanzu.vmware.com \
IMGPKG_REGISTRY_USERNAME=$TANZUNET_USERNAME \
IMGPKG_REGISTRY_PASSWORD=$TANZUNET_PASSWORD \
imgpkg copy \
-b registry.tanzu.vmware.com/tanzu-application-platform/full-deps-package-repo:1.7.3 \
--to-tar full-deps-1.7.3.tar \
--include-non-distributable-layers
ECR_REPO=$(aws ecr describe-repositories --region ap-northeast-1 --query 'repositories[?repositoryName==`full-deps-package-repo`].repositoryUri' --output text)
aws ecr get-login-password --region ap-northeast-1 | docker login ${ECR_REPO} -u AWS --password-stdin
imgpkg copy \
--tar full-deps-1.7.3.tar \
--to-repo ${ECR_REPO} \
--include-non-distributable-layers
tanzu package repository add full-deps-package-repo \
--url ${ECR_REPO}:1.7.3 \
--namespace tap-install
tanzu package install full-deps -p full-deps.buildservice.tanzu.vmware.com -v "> 0.0.0" -n tap-install --values-file tap-values.yaml
$ kubectl get pkgi -n tap-install
NAME PACKAGE NAME PACKAGE VERSION DESCRIPTION AGE
accelerator accelerator.apps.tanzu.vmware.com 1.7.7 Reconcile succeeded 36m
amr-observer amr-observer.apps.tanzu.vmware.com 0.2.1 Reconcile succeeded 36m
api-auto-registration apis.apps.tanzu.vmware.com 0.4.2 Reconcile succeeded 36m
appliveview backend.appliveview.tanzu.vmware.com 1.7.3 Reconcile succeeded 36m
appliveview-apiserver apiserver.appliveview.tanzu.vmware.com 1.7.3 Reconcile succeeded 37m
appliveview-connector connector.appliveview.tanzu.vmware.com 1.7.3 Reconcile succeeded 38m
appliveview-conventions conventions.appliveview.tanzu.vmware.com 1.7.3 Reconcile succeeded 37m
base-jammy-builder base-jammy-builder.buildpacks.tanzu.vmware.com 0.1.0 Reconcile succeeded 2m8s
base-jammy-stack base-jammy-stack.buildpacks.tanzu.vmware.com 0.1.74 Reconcile succeeded 2m26s
bitnami-services bitnami.services.tanzu.vmware.com 0.3.1 Reconcile succeeded 37m
buildservice buildservice.tanzu.vmware.com 1.12.4 Reconcile succeeded 38m
cartographer cartographer.tanzu.vmware.com 0.8.5 Reconcile succeeded 37m
cert-manager cert-manager.tanzu.vmware.com 2.4.2 Reconcile succeeded 38m
cnrs cnrs.tanzu.vmware.com 2.4.3 Reconcile succeeded 36m
contour contour.tanzu.vmware.com 1.25.3 Reconcile succeeded 37m
crossplane crossplane.tanzu.vmware.com 0.3.0 Reconcile succeeded 38m
developer-conventions developer-conventions.tanzu.vmware.com 0.14.2 Reconcile succeeded 37m
dotnet-core-buildpack dotnet-core.buildpacks.tanzu.vmware.com 2.8.3 Reconcile succeeded 2m26s
fluxcd-source-controller fluxcd.source.controller.tanzu.vmware.com 0.36.1+tanzu.2 Reconcile succeeded 38m
full-deps full-deps.buildservice.tanzu.vmware.com 1.7.55 Reconcile succeeded 2m28s
full-jammy-builder full-jammy-builder.buildpacks.tanzu.vmware.com 0.1.0 Reconcile succeeded 2m8s
full-jammy-stack full-jammy-stack.buildpacks.tanzu.vmware.com 0.1.129 Reconcile succeeded 2m26s
go-buildpack go.buildpacks.tanzu.vmware.com 2.2.3 Reconcile succeeded 2m26s
java-buildpack java.buildpacks.tanzu.vmware.com 9.12.2 Reconcile succeeded 2m26s
java-native-image-buildpack java-native-image.buildpacks.tanzu.vmware.com 7.10.1 Reconcile succeeded 2m26s
local-source-proxy local-source-proxy.apps.tanzu.vmware.com 0.2.1 Reconcile succeeded 38m
metadata-store metadata-store.apps.tanzu.vmware.com 1.7.2 Reconcile succeeded 36m
namespace-provisioner namespace-provisioner.apps.tanzu.vmware.com 0.5.0 Reconcile succeeded 37m
nodejs-buildpack nodejs.buildpacks.tanzu.vmware.com 2.3.3 Reconcile succeeded 2m26s
ootb-delivery-basic ootb-delivery-basic.tanzu.vmware.com 0.14.10 Reconcile succeeded 37m
ootb-supply-chain-testing-scanning ootb-supply-chain-testing-scanning.tanzu.vmware.com 0.14.10 Reconcile succeeded 37m
ootb-templates ootb-templates.tanzu.vmware.com 0.14.10 Reconcile succeeded 37m
php-buildpack php.buildpacks.tanzu.vmware.com 2.6.2 Reconcile succeeded 2m26s
procfile-buildpack procfile.buildpacks.tanzu.vmware.com 5.6.1 Reconcile succeeded 2m26s
python-buildpack python.buildpacks.tanzu.vmware.com 2.5.3 Reconcile succeeded 2m26s
ruby-buildpack ruby.buildpacks.tanzu.vmware.com 2.8.2 Reconcile succeeded 2m26s
scanning scanning.apps.tanzu.vmware.com 1.7.3 Reconcile succeeded 37m
service-bindings servicebinding.tanzu.vmware.com 0.10.3 Reconcile succeeded 37m
services-toolkit services-toolkit.tanzu.vmware.com 0.12.0 Reconcile succeeded 37m
source-controller controller.source.apps.tanzu.vmware.com 0.8.3 Reconcile succeeded 37m
spring-boot-conventions spring-boot-conventions.tanzu.vmware.com 1.7.3 Reconcile succeeded 37m
tap tap.tanzu.vmware.com 1.7.3 Reconcile succeeded 38m
tap-auth tap-auth.tanzu.vmware.com 1.1.0 Reconcile succeeded 38m
tap-gui tap-gui.tanzu.vmware.com 1.7.9 Reconcile succeeded 36m
tap-telemetry tap-telemetry.tanzu.vmware.com 0.7.0 Reconcile succeeded 38m
tekton-pipelines tekton.tanzu.vmware.com 0.50.3+tanzu.3 Reconcile succeeded 38m
tiny-jammy-builder tiny-jammy-builder.buildpacks.tanzu.vmware.com 0.1.0 Reconcile succeeded 2m8s
tiny-jammy-stack tiny-jammy-stack.buildpacks.tanzu.vmware.com 0.1.78 Reconcile succeeded 2m26s
web-servers-buildpack web-servers.buildpacks.tanzu.vmware.com 0.15.5 Reconcile succeeded 2m26s
$ kubectl get svc -n tanzu-system-ingress envoy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
envoy LoadBalancer 10.100.187.245 a6a44a1ab9fe14882b6a8cb90ae0b970-c12e1d630e8c3500.elb.ap-northeast-1.amazonaws.com 80:31413/TCP,443:31473/TCP 37m
$ kubectl get svc -n tanzu-system-ingress envoy -ojsonpath='{.status.loadBalancer.ingress[0].hostname}'
a6a44a1ab9fe14882b6a8cb90ae0b970-c12e1d630e8c3500.elb.ap-northeast-1.amazonaws.com
$ kubectl get httpproxy -A
NAMESPACE NAME FQDN TLS SECRET STATUS STATUS DESCRIPTION
api-auto-registration api-auto-registration-controller api-auto-registration.tap.52.69.252.111.sslip.io api-auto-registration-cert valid Valid HTTPProxy
metadata-store amr-cloudevent-handler-ingress amr-cloudevent-handler.tap.52.69.252.111.sslip.io amr-cloudevent-handler-ingress-cert valid Valid HTTPProxy
metadata-store amr-graphql-ingress amr-graphql.tap.52.69.252.111.sslip.io amr-ingress-cert valid Valid HTTPProxy
metadata-store metadata-store-ingress metadata-store.tap.52.69.252.111.sslip.io ingress-cert valid Valid HTTPProxy
tap-gui tap-gui tap-gui.tap.52.69.252.111.sslip.io tap-gui-cert valid Valid HTTPProxy
https://tap-gui.tap.52.69.252.111.sslip.io
$ kubectl get clusterbuilder
NAME LATESTIMAGE READY
base-jammy 198656008139.dkr.ecr.ap-northeast-1.amazonaws.com/tap-build-service:base-jammy-builder@sha256:2b602d503b56d18a67058f988344b2b0327986422ab1f864520f71e88c1265cb True
default 198656008139.dkr.ecr.ap-northeast-1.amazonaws.com/tap-build-service:default-builder@sha256:2b602d503b56d18a67058f988344b2b0327986422ab1f864520f71e88c1265cb True
full-jammy 198656008139.dkr.ecr.ap-northeast-1.amazonaws.com/tap-build-service:full-jammy-builder@sha256:c6031fa62b72108558c679121ab51b40b903a722001a353fc0b257d91042f38d True
tiny-jammy 198656008139.dkr.ecr.ap-northeast-1.amazonaws.com/tap-build-service:tiny-jammy-builder@sha256:befbf884e0ffe27fbd28da8757b7fc3a343027a47e5073b691d48586993e2ee2 True
Workloadの作成
kubectl create ns demo
kubectl label namespaces demo apps.tanzu.vmware.com/tap-ns=""
$ tanzu apps cluster-supply-chain list
NAME READY AGE
scanning-image-scan-to-url Ready 22m
source-test-scan-to-url Ready 22m
kubectl apply -f - -n demo << 'EOF'
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: skip-test-pipeline
labels:
apps.tanzu.vmware.com/pipeline: test
apps.tanzu.vmware.com/language: skip
spec:
params:
- name: source-url
- name: source-revision
tasks:
- name: test
params:
- name: source-url
value: $(params.source-url)
- name: source-revision
value: $(params.source-revision)
taskSpec:
params:
- name: source-url
- name: source-revision
steps:
- name: test
image: alpine
script: |-
echo 'skip'
---
EOF
kubectl apply -f - -n demo << 'EOF'
---
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
labels:
app.kubernetes.io/part-of: enable-in-gui
name: scan-policy
spec:
regoFile: |
package main
# Accepted Values: "Critical", "High", "Medium", "Low", "Negligible", "UnknownSeverity"
notAllowedSeverities := ["UnknownSeverity"]
ignoreCves := []
contains(array, elem) = true {
array[_] = elem
} else = false { true }
isSafe(match) {
severities := { e | e := match.ratings.rating.severity } | { e | e := match.ratings.rating[_].severity }
some i
fails := contains(notAllowedSeverities, severities[i])
not fails
}
isSafe(match) {
ignore := contains(ignoreCves, match.id)
ignore
}
deny[msg] {
comps := { e | e := input.bom.components.component } | { e | e := input.bom.components.component[_] }
some i
comp := comps[i]
vulns := { e | e := comp.vulnerabilities.vulnerability } | { e | e := comp.vulnerabilities.vulnerability[_] }
some j
vuln := vulns[j]
ratings := { e | e := vuln.ratings.rating.severity } | { e | e := vuln.ratings.rating[_].severity }
not isSafe(vuln)
msg = sprintf("CVE %s %s %s", [comp.name, vuln.id, ratings])
}
---
EOF
WORKLOADNAME=hello-nodejs
NAMESPACE=demo
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE} --region $AWS_REGION
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE}-bundle --region $AWS_REGION
tanzu apps workload apply hello-nodejs \
--app hello-nodejs \
--git-repo https://github.com/making/hello-nodejs \
--git-branch master \
--type web \
--label apps.tanzu.vmware.com/has-tests=true \
-n demo \
-y
tanzu apps workload tail hello-nodejs --namespace demo --timestamp --since 1h
$ tanzu apps workload get hello-nodejs --namespace demo
📡 Overview
name: hello-nodejs
type: web
namespace: demo
💾 Source
type: git
url: https://github.com/making/hello-nodejs
branch: master
revision: master@sha1:76f84e92aa878f170b5b5010bf4cd7cabfbf7e53
📦 Supply Chain
name: source-test-scan-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 5m49s gitrepositories.source.toolkit.fluxcd.io/hello-nodejs
source-tester True True 5m16s runnables.carto.run/hello-nodejs
image-provider True True 112s images.kpack.io/hello-nodejs
image-scanner True True 77s imagescans.scanning.apps.tanzu.vmware.com/hello-nodejs
config-provider True True 74s podintents.conventions.carto.run/hello-nodejs
app-config True True 74s configmaps/hello-nodejs
service-bindings True True 74s configmaps/hello-nodejs-with-claims
api-descriptors True True 74s configmaps/hello-nodejs-with-api-descriptors
config-writer True True 49s taskruns.tekton.dev/hello-nodejs-config-writer-7wxcs
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 45s imagerepositories.source.apps.tanzu.vmware.com/hello-nodejs-delivery
deployer True True 32s apps.kappctrl.k14s.io/hello-nodejs
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
hello-nodejs-00001-deployment-c67ff4c65-g8lnq 2/2 Running 0 45s
hello-nodejs-build-1-build-pod 0/1 Completed 0 5m16s
hello-nodejs-config-writer-7wxcs-pod 0/1 Completed 0 73s
hello-nodejs-jm5hb-test-pod 0/1 Completed 0 5m44s
scan-hello-nodejs-6kwmp-pod 0/6 Completed 0 111s
🚢 Knative Services
NAME READY URL
hello-nodejs Ready https://hello-nodejs.demo.tap.52.69.252.111.sslip.io
To see logs: "tanzu apps workload tail hello-nodejs --namespace demo --timestamp --since 1h"
$ curl -k https://hello-nodejs.demo.tap.52.69.252.111.sslip.io
Hello World!!! (hello-nodejs-00001-deployment-c67ff4c65-ctjhd)
Let's Encrypt (HTTP01 challenge)のClusterIssuerを作成
$ kubectl get certificate -A -owide | grep 'tap-ingress-selfsigned '
api-auto-registration api-auto-registration-cert True api-auto-registration-cert tap-ingress-selfsigned Certificate is up to date and has not expired 38m
demo route-8704ec08-eeab-457a-8e43-c3399b5b1b55 True route-8704ec08-eeab-457a-8e43-c3399b5b1b55 tap-ingress-selfsigned Certificate is up to date and has not expired 2m22s
metadata-store amr-cloudevent-handler-ingress-cert True amr-cloudevent-handler-ingress-cert tap-ingress-selfsigned Certificate is up to date and has not expired 38m
metadata-store amr-ingress-cert True amr-ingress-cert tap-ingress-selfsigned Certificate is up to date and has not expired 38m
metadata-store ingress-cert True ingress-cert tap-ingress-selfsigned Certificate is up to date and has not expired 38m
tap-gui tap-gui-cert True tap-gui-cert tap-ingress-selfsigned Certificate is up to date and has not expired 37m
cat <<EOF > cluster-issuer.yaml
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: user@yourdomain.com
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: contour
---
EOF
kubectl apply -f cluster-issuer.yaml
shared:
ingress_domain: ...
ingress_issuer: letsencrypt
# ...
tanzu package install tap -p tap.tanzu.vmware.com -v 1.7.3 --values-file tap-values.yaml -n tap-install
$ kubectl get certificate -A -owide | grep letsencrypt
api-auto-registration api-auto-registration-cert False api-auto-registration-cert letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 39m
demo route-8704ec08-eeab-457a-8e43-c3399b5b1b55 False route-8704ec08-eeab-457a-8e43-c3399b5b1b55 letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 3m42s
metadata-store amr-cloudevent-handler-ingress-cert False amr-cloudevent-handler-ingress-cert letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 39m
metadata-store amr-ingress-cert False amr-ingress-cert letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 39m
metadata-store ingress-cert False ingress-cert letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 39m
tap-gui tap-gui-cert False tap-gui-cert letsencrypt Fields on existing CertificateRequest resource not up to date: [spec.issuerRef] 39m
$ kubectl get pod -n demo
NAME READY STATUS RESTARTS AGE
cm-acme-http-solver-82bz9 1/1 Running 0 25s
hello-nodejs-00001-deployment-c67ff4c65-r59ts 2/2 Running 0 25s
hello-nodejs-build-1-build-pod 0/1 Completed 0 8m27s
hello-nodejs-config-writer-7wxcs-pod 0/1 Completed 0 4m24s
hello-nodejs-jm5hb-test-pod 0/1 Completed 0 8m55s
scan-hello-nodejs-6kwmp-pod 0/6 Completed 0 5m2s
$ kubectl get certificate -A -owide | grep letsencrypt
api-auto-registration api-auto-registration-cert True api-auto-registration-cert letsencrypt Certificate is up to date and has not expired 40m
demo route-8704ec08-eeab-457a-8e43-c3399b5b1b55 True route-8704ec08-eeab-457a-8e43-c3399b5b1b55 letsencrypt Certificate is up to date and has not expired 4m31s
metadata-store amr-cloudevent-handler-ingress-cert True amr-cloudevent-handler-ingress-cert letsencrypt Certificate is up to date and has not expired 40m
metadata-store amr-ingress-cert True amr-ingress-cert letsencrypt Certificate is up to date and has not expired 40m
metadata-store ingress-cert True ingress-cert letsencrypt Certificate is up to date and has not expired 40m
tap-gui tap-gui-cert True tap-gui-cert letsencrypt Certificate is up to date and has not expired 40m
$ curl https://hello-nodejs.demo.tap.52.69.252.111.sslip.io
Hello World!!! (hello-nodejs-00001-deployment-c67ff4c65-5x684)
(Optional) Metrics Serverのインストール
tanzu package repository add tanzu-core \
--url projects.registry.vmware.com/tkg/packages/core/repo:v1.27.5_vmware.1-tkg.3 \
--namespace tkg-system \
--create-namespace
tanzu package install -n tkg-system metrics-server -p metrics-server.tanzu.vmware.com -v 0.6.2+vmware.1-tkg.4
$ kubectl get deploy -n kube-system metrics-server
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 1/1 1 1 79s
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
ip-192-168-19-134.ap-northeast-1.compute.internal 195m 4% 1797Mi 12%
ip-192-168-39-153.ap-northeast-1.compute.internal 93m 2% 1340Mi 9%
ip-192-168-79-97.ap-northeast-1.compute.internal 101m 2% 1930Mi 13%
Local Source Proxy
mkdir -p hello-world/public
cd hello-world
cat <<EOF > public/index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
EOF
WORKLOADNAME=hello-world
NAMESPACE=demo
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE} --region $AWS_REGION
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE}-bundle --region $AWS_REGION
tanzu apps workload apply hello-world \
--local-path ./ \
--type web \
--app hello-world \
--label apps.tanzu.vmware.com/has-tests=true \
--build-env BP_WEB_SERVER=nginx \
-n demo \
-y
cd ..
tanzu apps workload tail hello-world --namespace demo --timestamp --since 1h
$ tanzu apps workload get -n demo hello-world
📡 Overview
name: hello-world
type: web
namespace: demo
💾 Source
type: source image
image: 532912407632.dkr.ecr.ap-northeast-1.amazonaws.com/tap-lsp:demo-hello-world@sha256:cff5552ec1c0e57e14f7ff7060bc308fd8f002facdf683795814130d73258aa0
📦 Supply Chain
name: source-test-scan-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 5m39s imagerepositories.source.apps.tanzu.vmware.com/hello-world
source-tester True True 5m11s runnables.carto.run/hello-world
image-provider True True 113s images.kpack.io/hello-world
image-scanner True True 83s imagescans.scanning.apps.tanzu.vmware.com/hello-world
config-provider True True 80s podintents.conventions.carto.run/hello-world
app-config True True 80s configmaps/hello-world
service-bindings True True 79s configmaps/hello-world-with-claims
api-descriptors True True 79s configmaps/hello-world-with-api-descriptors
config-writer True True 70s taskruns.tekton.dev/hello-world-config-writer-5gs4x
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 38s imagerepositories.source.apps.tanzu.vmware.com/hello-world-delivery
deployer True True 3s apps.kappctrl.k14s.io/hello-world
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
hello-world-00001-deployment-5f78b64f79-lp9zr 2/2 Running 0 37s
hello-world-build-1-build-pod 0/1 Completed 0 5m10s
hello-world-config-writer-5gs4x-pod 0/1 Completed 0 79s
hello-world-hd45c-test-pod 0/1 Completed 0 5m36s
scan-hello-world-mxjpt-pod 0/6 Completed 0 113s
🚢 Knative Services
NAME READY URL
hello-world Ready https://hello-world.demo.tap.52.69.252.111.sslip.io
To see logs: "tanzu apps workload tail hello-world --namespace demo --timestamp --since 1h"
$ curl https://hello-world.demo.tap.52.69.252.111.sslip.io
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
Bitnami ServiceでPostgreSQLを動的プロビジョニング
WORKLOADNAME=blog-api
NAMESPACE=demo
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE} --region $AWS_REGION
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE}-bundle --region $AWS_REGION
$ kubectl get clusterinstanceclass
NAME DESCRIPTION READY REASON
kafka-unmanaged Kafka by Bitnami True Ready
mongodb-unmanaged MongoDB by Bitnami True Ready
mysql-unmanaged MySQL by Bitnami True Ready
postgresql-unmanaged PostgreSQL by Bitnami True Ready
rabbitmq-unmanaged RabbitMQ by Bitnami True Ready
redis-unmanaged Redis by Bitnami True Ready
tanzu service class-claim create blog-db --class postgresql-unmanaged --parameter storageGB=1 -n demo
$ tanzu services class-claims get blog-db --namespace demo
Name: blog-db
Namespace: demo
Claim Reference: services.apps.tanzu.vmware.com/v1alpha1:ClassClaim:blog-db
Class Reference:
Name: postgresql-unmanaged
Parameters:
storageGB: 1
Status:
Ready: True
Claimed Resource:
Name: 1503b835-872b-4dc7-a5f1-209ac1e69d63
Namespace: demo
Group:
Version: v1
Kind: Secret
$ kubectl get secret -n demo 1503b835-872b-4dc7-a5f1-209ac1e69d63 -ojson | jq '.data | map_values(@base64d)'
{
"database": "blog-db-mjj8p",
"host": "10.100.45.57",
"password": "qD9dZ20PDmTCiNo8vOj5Fd132HrnOmx8",
"port": "5432",
"provider": "bitnami",
"type": "postgresql",
"username": "postgres"
}
$ kubectl get sts -A
NAMESPACE NAME READY AGE
blog-db-mjj8p blog-db-mjj8p 1/1 1h24m
metadata-store metadata-store-db 1/1 2h58m
tanzu apps workload apply blog-api \
--app blog-api \
--git-repo https://github.com/categolj/blog-api \
--git-branch main \
--type web \
--annotation autoscaling.knative.dev/minScale=1 \
--label apps.tanzu.vmware.com/has-tests=true \
--service-ref blog-db=services.apps.tanzu.vmware.com/v1alpha1:ClassClaim:blog-db \
--build-env BP_JVM_VERSION=17 \
-n demo \
-y
tanzu apps workload tail blog-api --namespace demo --timestamp --since 1h
$ tanzu apps workload get -n demo blog-api
📡 Overview
name: blog-api
type: web
namespace: demo
💾 Source
type: git
url: https://github.com/categolj/blog-api
branch: main
revision: main@sha1:ee957ac5ce3a96db766008217e4f3bf0968af540
📦 Supply Chain
name: source-test-scan-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 37m gitrepositories.source.toolkit.fluxcd.io/blog-api
source-tester True True 37m runnables.carto.run/blog-api
image-provider True True 29m images.kpack.io/blog-api
image-scanner True True 28m imagescans.scanning.apps.tanzu.vmware.com/blog-api
config-provider True True 28m podintents.conventions.carto.run/blog-api
app-config True True 28m configmaps/blog-api
service-bindings True True 28m configmaps/blog-api-with-claims
api-descriptors True True 28m configmaps/blog-api-with-api-descriptors
config-writer True True 28m taskruns.tekton.dev/blog-api-config-writer-hjn29
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 27m imagerepositories.source.apps.tanzu.vmware.com/blog-api-delivery
deployer True True 26m apps.kappctrl.k14s.io/blog-api
💬 Messages
No messages found.
🔁 Services
CLAIM NAME KIND API VERSION
blog-db blog-db ClassClaim services.apps.tanzu.vmware.com/v1alpha1
🛶 Pods
NAME READY STATUS RESTARTS AGE
blog-api-00001-deployment-5766885df6-dwcds 2/2 Running 0 27m
blog-api-6mvh2-test-pod 0/1 Completed 0 37m
blog-api-build-1-build-pod 0/1 Completed 0 37m
blog-api-config-writer-hjn29-pod 0/1 Completed 0 28m
scan-blog-api-wlwdm-pod 0/6 Completed 0 29m
🚢 Knative Services
NAME READY URL
blog-api Ready https://blog-api.demo.tap.52.69.252.111.sslip.io
curl -s https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/template.md > template.md
curl -s -u admin:changeme -XPUT https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/1 -H "Content-Type: text/markdown" -d "$(cat template.md)"
curl -s https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/1 | jq .
{
"entryId": 1,
"frontMatter": {
"title": "Welcome to CategolJ!",
"categories": [
{
"name": "Blog"
},
{
"name": "Posts"
},
{
"name": "Templates"
}
],
"tags": [
{
"name": "Hello World"
},
{
"name": "CategolJ"
}
]
},
"content": "Welcome\n\n**Hello world**, this is my first Categolj blog post.\n\nI hope you like it!",
"created": {
"name": "admin",
"date": "2023-12-13T07:24:29.851875Z"
},
"updated": {
"name": "admin",
"date": "2023-12-13T07:24:29.851875Z"
}
}
App Live View
https://github.com/categolj/tap-catalog-info/blob/main/blog-api.yaml
AWS ServicesでRDSの動的プロビジョニング
PRIVATE_SUBNET_ID_1=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPrivate$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')A" --query "Subnets[*].SubnetId" --output text)
PRIVATE_SUBNET_ID_2=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPrivate$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')C" --query "Subnets[*].SubnetId" --output text)
PRIVATE_SUBNET_ID_3=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPrivate$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')D" --query "Subnets[*].SubnetId" --output text)
aws rds create-db-subnet-group \
--db-subnet-group-name tap-aws-services \
--db-subnet-group-description "TAP AWS Services Subnet Group" \
--subnet-ids "[\"$PRIVATE_SUBNET_ID_1\", \"$PRIVATE_SUBNET_ID_2\", \"$PRIVATE_SUBNET_ID_3\"]" \
--region $AWS_REGION
PUBLIC_SUBNET_ID_1=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPublic$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')A" --query "Subnets[*].SubnetId" --output text)
PUBLIC_SUBNET_ID_2=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPublic$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')C" --query "Subnets[*].SubnetId" --output text)
PUBLIC_SUBNET_ID_3=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=eksctl-$(echo $EKS_CLUSTER_NAME)-cluster/SubnetPublic$(echo $AWS_REGION | tr 'a-z' 'A-Z' | tr -d '-')D" --query "Subnets[*].SubnetId" --output text)
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=eksctl-${EKS_CLUSTER_NAME}-cluster/VPC" --query "Vpcs[0].VpcId" --output text)
SG_ID=$(aws ec2 create-security-group --group-name tap-aws-services-postgresql --description "TAP AWS Services PostgreSQL" --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=tap-aws-services-postgresql}]' --vpc-id $VPC_ID --region $AWS_REGION --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 5432 --cidr $(aws ec2 describe-subnets --subnet-ids $PUBLIC_SUBNET_ID_1 --query 'Subnets[0].CidrBlock' --output text)
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 5432 --cidr $(aws ec2 describe-subnets --subnet-ids $PUBLIC_SUBNET_ID_2 --query 'Subnets[0].CidrBlock' --output text)
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 5432 --cidr $(aws ec2 describe-subnets --subnet-ids $PUBLIC_SUBNET_ID_3 --query 'Subnets[0].CidrBlock' --output text)
$ aws ec2 describe-security-groups --group-ids $SG_ID --output yaml
SecurityGroups:
- Description: TAP AWS Services PostgreSQL
GroupId: sg-09392b8928b5ea869
GroupName: tap-aws-services-postgresql
IpPermissions:
- FromPort: 5432
IpProtocol: tcp
IpRanges:
- CidrIp: 192.168.64.0/19
- CidrIp: 192.168.0.0/19
- CidrIp: 192.168.32.0/19
Ipv6Ranges: []
PrefixListIds: []
ToPort: 5432
UserIdGroupPairs: []
IpPermissionsEgress:
- IpProtocol: '-1'
IpRanges:
- CidrIp: 0.0.0.0/0
Ipv6Ranges: []
PrefixListIds: []
UserIdGroupPairs: []
OwnerId: '532912407632'
Tags:
- Key: Name
Value: tap-aws-services-postgresql
VpcId: vpc-045d0ec148d20f5e1
cat <<EOF > aws-services-values.yaml
---
postgresql:
enabled: true
region: ${AWS_REGION}
provider_config_ref:
name: aws-provider
infrastructure:
subnet_group:
name: tap-aws-services
security_groups:
- id: ${SG_ID}
instance_configuration:
instance_class: db.t4g.micro
engine_version: "15.5" # See aws rds describe-db-engine-versions --default-only --engine postgres --output yaml
skip_final_snapshot: true
publicly_accessible: false
maintenance_window: Mon:00:00-Mon:03:00
---
EOF
https://github.com/upbound/provider-aws/blob/main/AUTHENTICATION.md#authentication-using-irsa
cat << EOF > aws-services-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDCPROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDCPROVIDER}:aud": "sts.amazonaws.com"
},
"StringLike": {
"${OIDCPROVIDER}:sub": [
"system:serviceaccount:crossplane-system:provider-aws-*"
]
}
}
}
]
}
EOF
cat <<EOF > aws-services-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:CreateDBInstance",
"rds:DeleteDBInstance",
"rds:DescribeDBInstances",
"rds:StopDBInstance",
"rds:StartDBInstance",
"rds:ModifyDBInstance",
"rds:AddTagsToResource",
"rds:DescribeDBSubnetGroups",
"rds:ListTagsForResource",
"ec2:DescribeSecurityGroups"
],
"Resource": "*"
}
]
}
EOF
aws iam create-role --role-name tap-aws-services --assume-role-policy-document file://aws-services-trust-policy.json
aws iam put-role-policy --role-name tap-aws-services --policy-name tapAwsServicesPolicy --policy-document file://aws-services-policy.json
cat <<EOF > aws-services-overlay.yaml
---
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"kind": "ControllerConfig"}), expects="1+"
---
metadata:
#@overlay/match missing_ok=True
annotations:
#@overlay/match missing_ok=True
eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/tap-aws-services
---
#! Placeholder CRD that allows us to create a ProviderConfig
#! before the actual Provider has been installed. Uses "exists"
#! annotation so that the real CRD can be installed by the Provider.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: providerconfigs.aws.upbound.io
annotations:
kapp.k14s.io/exists: ""
spec:
group: aws.upbound.io
versions:
- name: v1beta1
names:
kind: ProviderConfig
---
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-provider
spec:
credentials:
source: IRSA
---
EOF
tanzu package install aws-services -p aws.services.tanzu.vmware.com --version 0.1.0 -n tap-install --values-file aws-services-values.yaml --ytt-overlay-file aws-services-overlay.yaml
$ kubectl get securitygroup,subnetgroup
NAME READY SYNCED EXTERNAL-NAME AGE
securitygroup.ec2.aws.upbound.io/sg-09392b8928b5ea869 True True sg-09392b8928b5ea869 57s
NAME READY SYNCED EXTERNAL-NAME AGE
subnetgroup.rds.aws.upbound.io/tap-aws-services True tap-aws-services 51s
⚠️ subnetgroupの
SYNCED
がFalse
のままで、describeするとreading RDS DB Subnet Group (tap-aws-services): InvalidParameterValue: Missing necessary credentials. Please check http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAM.ServiceLinkedRoles.html
というエラーが出ている場合は、
AWSServiceRoleForRDS
ロールがないと思われます。初めてRDSを使用する場合はこのエラーが出ます。
この場合は次のコマンドを実行してください。aws iam create-service-linked-role --aws-service-name rds.amazonaws.com
$ tanzu service class list
NAME DESCRIPTION
kafka-unmanaged Kafka by Bitnami
mongodb-unmanaged MongoDB by Bitnami
mysql-unmanaged MySQL by Bitnami
postgresql-managed-aws PostgreSQL databases powered by AWS RDS <<-----
postgresql-unmanaged PostgreSQL by Bitnami
rabbitmq-unmanaged RabbitMQ by Bitnami
redis-unmanaged Redis by Bitnami
tanzu service class-claim delete blog-db -n demo -y
tanzu service class-claim create blog-db --class postgresql-managed-aws --parameter storageGB=20 -n demo
$ tanzu services class-claims get blog-db --namespace demo
Name: blog-db
Namespace: demo
Claim Reference: services.apps.tanzu.vmware.com/v1alpha1:ClassClaim:blog-db
Class Reference:
Name: postgresql-managed-aws
Parameters:
storageGB: 20
Status:
Ready: True
Claimed Resource:
Name: 52840e97-b5b6-45a4-a1f7-64cbad6e7608
Namespace: demo
Group:
Version: v1
Kind: Secret
$ kubectl get instances.rds
NAME READY SYNCED EXTERNAL-NAME AGE
blog-db-hwvwl-djcfz True True blog-db-hwvwl-djcfz 5m10s
$ kubectl get secret -n demo 52840e97-b5b6-45a4-a1f7-64cbad6e7608 -ojson | jq '.data | map_values(@base64d)'
{
"database": "postgres",
"host": "blog-db-hwvwl-djcfz.crcoo11tlq3d.ap-northeast-1.rds.amazonaws.com",
"password": "mH7DdYLfuIAyWdeEqavYNSjQxia",
"port": "5432",
"provider": "aws",
"type": "postgresql",
"username": "adminuser"
}
kubectl delete app blog-api -n demo
$ kubectl get app -n demo blog-api
NAME DESCRIPTION SINCE-DEPLOY AGE
blog-api Reconciling 10s 10s
$ kubectl logs -n demo -l app.kubernetes.io/component=run,app.kubernetes.io/part-of=blog-api -c workload --tail=-1 | grep 'rds\.'
{"@timestamp":"2023-12-15T04:01:41.986Z","log.level": "INFO","message":"Database: jdbc:postgresql://blog-db-hwvwl-djcfz.crcoo11tlq3d.ap-northeast-1.rds.amazonaws.com:5432/postgres (PostgreSQL 15.5)","ecs.version": "1.2.0","service.name":"blog-api","event.dataset":"blog-api","process.thread.name":"main","log.logger":"org.flywaydb.core.FlywayExecutor","traceId":"84bc2ae8b8ef5062b7df4d67ceb3021c","spanId":"23467c245fc9d590"}
curl -s https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/template.md > template.md
curl -s -u admin:changeme -XPUT https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/1 -H "Content-Type: text/markdown" -d "$(cat template.md)"
curl -s https://blog-api.demo.tap.52.69.252.111.sslip.io/entries/1 | jq .
Workloadのソースコード取得元にAWS CodeCommitを使用
⚠️ IAM Userの作成は許可されていないことがあります。VMware社員でCloud Gateを使ってアカウントを払い出している場合は以下のコマンドは許可されていません。
aws iam create-user --user-name tap-git
aws iam attach-user-policy --user-name tap-git --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
aws iam create-service-specific-credential --user-name tap-git --service-name codecommit.amazonaws.com > codecommit-user.json
aws codecommit create-repository --repository-name hello-spring-boot --repository-description "Hello Spring Boot" --region $AWS_REGION > codecommit-repo.json
GIT_USERNAME=$(cat codecommit-user.json | jq -r .ServiceSpecificCredential.ServiceUserName)
GIT_PASSWORD=$(cat codecommit-user.json | jq -r .ServiceSpecificCredential.ServicePassword)
GIT_URL=$(cat codecommit-repo.json | jq -r .repositoryMetadata.cloneUrlHttp)
curl https://start.spring.io/starter.zip \
-s \
-d type=maven-project \
-d language=java \
-d bootVersion=3.2.0 \
-d baseDir=hello-spring-boot \
-d groupId=com.example \
-d artifactId=hello-spring-boot \
-d name=hello-spring-boot \
-d description=Demo \
-d packageName=com.example.demo \
-d packaging=jar \
-d javaVersion=17 \
-d dependencies=web,actuator \
-o hello-spring-boot.zip
unzip hello-spring-boot.zip
cd hello-spring-boot
cat <<EOF > ./src/main/java/com/example/demo/HelloController.java
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping(path = "/")
public String hello() {
return "Hello World!";
}
}
EOF
git init
git add -A
git commit -m "initial commit"
git remote add origin https://$GIT_USERNAME:$GIT_PASSWORD@$(echo $GIT_URL | sed 's|https://||g')
git push origin main
$ kubectl get sa -n demo default -oyaml
apiVersion: v1
imagePullSecrets:
- name: registries-credentials
kind: ServiceAccount
metadata:
# ...
name: default
namespace: demo
# ...
secrets:
- name: registries-credentials
cat << EOF > workload-git-auth.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: workload-git-auth
namespace: tap-install
type: Opaque
stringData:
content.yaml: |
git:
host: "https://git-codecommit.${AWS_REGION}.amazonaws.com"
username: "${GIT_USERNAME}"
token: "${GIT_PASSWORD}"
---
EOF
kubectl apply -f workload-git-auth.yaml
cat <<EOF >> tap-values.yaml
namespace_provisioner:
controller: true
additional_sources:
- git:
url: https://github.com/making/namespace-provisioner-samples.git
ref: origin/main
subPath: git-basic
path: _ytt_lib/git-basic
import_data_values_secrets:
- name: workload-git-auth
namespace: tap-install
create_export: true
default_parameters:
supply_chain_service_account:
secrets:
- git-basic
EOF
tanzu package install tap -p tap.tanzu.vmware.com -v 1.7.3 --values-file tap-values.yaml -n tap-install
$ kubectl get sa -n demo default -oyaml
apiVersion: v1
imagePullSecrets:
- name: registries-credentials
kind: ServiceAccount
metadata:
# ...
name: default
namespace: demo
# ...
secrets:
- name: registries-credentials
- name: git-basic # <<----
$ kubectl get secret -n demo git-basic
NAME TYPE DATA AGE
git-basic kubernetes.io/basic-auth 2 3m49s
WORKLOADNAME=hello-spring-boot
NAMESPACE=demo
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE} --region $AWS_REGION
aws ecr create-repository --repository-name tanzu-application-platform/${WORKLOADNAME}-${NAMESPACE}-bundle --region $AWS_REGION
tanzu apps workload apply hello-spring-boot \
--app hello-spring-boot \
--git-repo $GIT_URL \
--git-branch main \
--type web \
--param gitops_ssh_secret=git-basic \
--annotation autoscaling.knative.dev/minScale=1 \
--label apps.tanzu.vmware.com/has-tests=true \
--build-env BP_JVM_VERSION=17 \
-n demo \
-y
tanzu apps workload tail hello-spring-boot --namespace demo --timestamp --since 1h
$ tanzu apps workload get hello-spring-boot --namespace demo
📡 Overview
name: hello-spring-boot
type: web
namespace: demo
💾 Source
type: git
url: https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/hello-spring-boot
branch: main
revision: main@sha1:15120369817b61428602e1d28a1e083ccc14bea3
📦 Supply Chain
name: source-test-scan-to-url
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 6m38s gitrepositories.source.toolkit.fluxcd.io/hello-spring-boot
source-tester True True 6m22s runnables.carto.run/hello-spring-boot
image-provider True True 2m48s images.kpack.io/hello-spring-boot
image-scanner True True 2m14s imagescans.scanning.apps.tanzu.vmware.com/hello-spring-boot
config-provider True True 2m7s podintents.conventions.carto.run/hello-spring-boot
app-config True True 2m7s configmaps/hello-spring-boot
service-bindings True True 2m7s configmaps/hello-spring-boot-with-claims
api-descriptors True True 2m7s configmaps/hello-spring-boot-with-api-descriptors
config-writer True True 2m2s taskruns.tekton.dev/hello-spring-boot-config-writer-dddmc
🚚 Delivery
name: delivery-basic
NAME READY HEALTHY UPDATED RESOURCE
source-provider True True 100s imagerepositories.source.apps.tanzu.vmware.com/hello-spring-boot-delivery
deployer True True 59s apps.kappctrl.k14s.io/hello-spring-boot
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
hello-spring-boot-00001-deployment-5c6c58b777-jg5bn 2/2 Running 0 99s
hello-spring-boot-build-1-build-pod 0/1 Completed 0 6m21s
hello-spring-boot-config-writer-dddmc-pod 0/1 Completed 0 2m10s
hello-spring-boot-v846b-test-pod 0/1 Completed 0 6m35s
scan-hello-spring-boot-v242b-pod 0/6 Completed 0 2m48s
🚢 Knative Services
NAME READY URL
hello-spring-boot Ready https://hello-spring-boot.demo.tap.52.69.252.111.sslip.io
$ curl https://hello-spring-boot.demo.tap.52.69.252.111.sslip.io
Hello World!
sed -i.bak 's/Hello World/Hello TAP/' src/main/java/com/example/demo/HelloController.java
rm -f src/main/java/com/example/demo/HelloController.java.bak
git add src/main/java/com/example/demo/HelloController.java
git commit -m "Update"
git push origin main
tanzu apps workload tail hello-spring-boot --namespace demo --timestamp --since 5m
$ curl https://hello-spring-boot.demo.tap.52.69.252.111.sslip.io
Hello TAP!
EnvoyのLoad Balancerに対するInboundのIP制限
https://repost.aws/knowledge-center/eks-cidr-ip-address-loadbalancer
cat <<EOF > contour-envoy-lb-source-ranges.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: contour-envoy-lb-source-ranges
namespace: tap-install
type: Opaque
stringData:
contour-envoy-lb-source-ranges.yaml: |
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"kind": "Service", "metadata": {"name": "envoy"}})
---
spec:
#@overlay/match missing_ok=True
loadBalancerSourceRanges:
- 66.170.99.1/32
- 57.181.54.124/32
---
EOF
kubectl apply -f contour-envoy-lb-source-ranges.yaml
cat <<EOF >> tap-values.yaml
package_overlays:
- name: contour
secrets:
- name: contour-envoy-lb-source-ranges
EOF
⚠️ この方法を使用すると、Let's EncryptによるHTTP-01チャレンジができなくなります。(証明書が生成されなくなります)
チャレンジ方式をDNS-01にする (Route53などpublicなDNSサービスが必要です) か、shared.ingress_issuer
の設定を削除して、自己署名証明書に戻す必要があります。
tanzu package install tap -p tap.tanzu.vmware.com -v 1.7.3 --values-file tap-values.yaml -n tap-install
$ kubectl get svc -n tanzu-system-ingress envoy -ojsonpath='{.spec.loadBalancerSourceRanges}'
["66.170.99.1/32","57.181.54.124/32"]
アンインストール
kubectl delete workload -A --all
kubectl delete classclaim -A --all
tanzu package installed delete -n tap-install aws-services -y
tanzu package installed delete -n tap-install full-deps -y
tanzu package installed delete -n tap-install tap -y
kubectl delete pvc -A --all
aws ec2 delete-security-group --group-id ${SG_ID} --region $AWS_REGION
aws rds delete-db-subnet-group --db-subnet-group-name tap-aws-services --region $AWS_REGION
aws iam delete-role-policy --role-name tap-aws-services --policy-name tapAwsServicesPolicy
aws iam delete-role --role-name tap-aws-services
aws iam delete-role-policy --role-name tap-build-service --policy-name tapBuildServicePolicy
aws iam delete-role-policy --role-name tap-workload --policy-name tapWorkload
aws iam delete-role-policy --role-name tap-local-source-proxy --policy-name tapLocalSourcePolicy
aws iam delete-role --role-name tap-build-service
aws iam delete-role --role-name tap-workload
aws iam delete-role --role-name tap-local-source-proxy
aws ecr delete-repository --repository-name tap-images --force --region $AWS_REGION
aws ecr delete-repository --repository-name tap-build-service --force --region $AWS_REGION
aws ecr delete-repository --repository-name full-deps-package-repo --force --region $AWS_REGION
aws ecr delete-repository --repository-name tap-lsp --force --region $AWS_REGION
aws ecr delete-repository --repository-name tanzu-cluster-essentials --force --region $AWS_REGION
aws ecr delete-repository --repository-name tanzu-application-platform/hello-nodejs-demo --force --region $AWS_REGION
aws ecr delete-repository --repository-name tanzu-application-platform/hello-nodejs-demo-bundle --force --region $AWS_REGION
aws ecr delete-repository --repository-name tanzu-application-platform/hello-world-demo --force --region $AWS_REGION
aws ecr delete-repository --repository-name tanzu-application-platform/hello-world-demo-bundle --force --region $AWS_REGION
# ...
eksctl delete cluster -f eks-cluster-config.yaml --force --disable-nodegroup-eviction --parallel 3 --wait
aws ec2 release-address --allocation-id $(jq -r '.AllocationId' envoy-eip-1.json)
aws ec2 release-address --allocation-id $(jq -r '.AllocationId' envoy-eip-2.json)
aws ec2 release-address --allocation-id $(jq -r '.AllocationId' envoy-eip-3.json)